1.1补充
This commit is contained in:
@@ -65,10 +65,12 @@
|
||||
"showdown": "1.9.0",
|
||||
"sortablejs": "1.8.4",
|
||||
"tui-editor": "1.3.3",
|
||||
"v-viewer": "^1.5.1",
|
||||
"vue": "2.6.10",
|
||||
"vue-count-to": "^1.0.13",
|
||||
"vue-i18n": "7.3.2",
|
||||
"vue-loader": "^15.9.2",
|
||||
"vue-photo-preview": "^1.1.3",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "3.0.2",
|
||||
"vue-splitpane": "1.0.4",
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {}
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
getList: `/authority//order/findReturnInterventionList`,
|
||||
getInfo: `/authority/order/getReturnInterventionDetail`
|
||||
}
|
||||
export default {
|
||||
// 售后平台介入列表
|
||||
getList(data) {
|
||||
return axiosApi({
|
||||
method: 'POST',
|
||||
url: apiList.getList,
|
||||
data
|
||||
})
|
||||
},
|
||||
getInfo(id) {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: `${apiList.getInfo}/${id}`
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/application/page`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/application`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/application`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/application`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/application/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/application/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/application/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/area/page`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/area`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/area`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/area`
|
||||
},
|
||||
query: {
|
||||
method: 'POST',
|
||||
url: `/authority/area/query`
|
||||
},
|
||||
tree: {
|
||||
method: 'GET',
|
||||
url: `/authority/area/tree`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page(data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
tree(data) {
|
||||
return axiosApi({
|
||||
...apiList.tree,
|
||||
data
|
||||
})
|
||||
},
|
||||
query(data) {
|
||||
return axiosApi({
|
||||
...apiList.query,
|
||||
data
|
||||
})
|
||||
},
|
||||
save(data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update(data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete(data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
check(code, id) {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: `/authority/area/check/` + code,
|
||||
data: { id: id }
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/file/attachment/page`
|
||||
},
|
||||
upload: {
|
||||
method: 'POST',
|
||||
url: `/file/attachment/upload`
|
||||
},
|
||||
download: {
|
||||
method: 'GET',
|
||||
url: `/file/attachment/download`
|
||||
},
|
||||
downloadBiz: {
|
||||
method: 'GET',
|
||||
url: `/file/attachment/download/biz`
|
||||
},
|
||||
downloadUrl: {
|
||||
method: 'GET',
|
||||
url: `/file/attachment/download/url`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/file/attachment`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
upload (data) {
|
||||
return axiosApi({
|
||||
...apiList.upload,
|
||||
data
|
||||
})
|
||||
},
|
||||
download (data) {
|
||||
return axiosApi({
|
||||
...apiList.download,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
downloadBiz (data) {
|
||||
return axiosApi({
|
||||
...apiList.downloadBiz,
|
||||
data
|
||||
})
|
||||
},
|
||||
downloadUrl (data) {
|
||||
return axiosApi({
|
||||
...apiList.downloadUrl,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/dictionary/page`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/dictionary`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/dictionary`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/dictionary`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -5,7 +5,9 @@ const apiList = {
|
||||
getDetail: '/authority/cashOutDetail/audit/',
|
||||
audiCash: '/authority/cashOutDetail/audit',
|
||||
getDepositList: `/authority/depositJournal/page`, // 保证金列表
|
||||
getDepositSum: `/authority/depositJournal/summary` // 保证金总金额
|
||||
getDepositSum: `/authority/depositJournal/summary`, // 保证金总金额
|
||||
getDayList: `/authority/journalDetail/platform-finance-page`,
|
||||
getSummary: `/authority/journalDetail/platform-finance-summary`
|
||||
}
|
||||
export default {
|
||||
// 提现审核列表
|
||||
@@ -45,5 +47,20 @@ export default {
|
||||
method: 'POST',
|
||||
url: apiList.getDepositSum
|
||||
})
|
||||
},
|
||||
// 平台流水列表
|
||||
getDayList(data) {
|
||||
return axiosApi({
|
||||
method: 'POST',
|
||||
url: apiList.getDayList,
|
||||
data
|
||||
})
|
||||
},
|
||||
// 平台财务统计
|
||||
getSummary() {
|
||||
return axiosApi({
|
||||
method: 'POST',
|
||||
url: apiList.getSummary
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/loginLog/page`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/loginLog`
|
||||
},
|
||||
clear: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/loginLog/clear`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/loginLog/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/loginLog/export`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page(data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete(data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
clear(data) {
|
||||
return axiosApi({
|
||||
...apiList.clear,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview(data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export(data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
getPlatformMenu: `/authority/menu/tree`,
|
||||
getAllMerchanMenu: `/authority/menu/getAllTenantMenu`,
|
||||
getSpecialMerchantMenu: `/authority/menu/getSpecifiedTenantMenu`,
|
||||
saveMenu: `/authority/menu/syncMenu`
|
||||
}
|
||||
export default {
|
||||
// 平台所有菜单
|
||||
getPlatformMenu() {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: apiList.getPlatformMenu
|
||||
})
|
||||
},
|
||||
// 查询所有商家菜单
|
||||
getAllMerchanMenu() {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: apiList.getAllMerchanMenu
|
||||
})
|
||||
},
|
||||
// 查询指定商家菜单
|
||||
getSpecialMerchantMenu(id) {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: `${apiList.getSpecialMerchantMenu}/${id}`
|
||||
})
|
||||
},
|
||||
// 同步菜单
|
||||
saveMenu(data) {
|
||||
return axiosApi({
|
||||
method: 'POST',
|
||||
url: apiList.saveMenu,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
url: `/msgs/msgsCenterInfo/page`,
|
||||
method: 'POST'
|
||||
},
|
||||
mark: {
|
||||
url: `/msgs/msgsCenterInfo/mark`,
|
||||
method: 'GET'
|
||||
},
|
||||
save: {
|
||||
url: `/msgs/msgsCenterInfo`,
|
||||
method: 'POST'
|
||||
},
|
||||
delete: {
|
||||
url: `/msgs/msgsCenterInfo`,
|
||||
method: 'DELETE'
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/msgs/msgsCenterInfo/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/msgs/msgsCenterInfo/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/msgs/msgsCenterInfo/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data, custom = {}) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data,
|
||||
custom
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
mark (data) {
|
||||
return axiosApi({
|
||||
...apiList.mark,
|
||||
data
|
||||
})
|
||||
},
|
||||
get (id) {
|
||||
return axiosApi({
|
||||
url: `/msgs/msgsCenterInfo/${id}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/optLog/page`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/optLog`
|
||||
},
|
||||
clear: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/optLog/clear`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/optLog/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/optLog/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/optLog/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
clear (data) {
|
||||
return axiosApi({
|
||||
...apiList.clear,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
allTree: {
|
||||
method: 'GET',
|
||||
url: `/authority/org/tree`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/org`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/org`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/org`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/org/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/org/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/org/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
allTree (data) {
|
||||
return axiosApi({
|
||||
...apiList.allTree,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/parameter/page`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/parameter`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/parameter`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/parameter`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/parameter/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/parameter/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/parameter/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data, custom = {}) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data,
|
||||
custom
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/resource/page`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/resource`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/resource`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/resource`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
url: `/authority/role/page`,
|
||||
method: 'POST'
|
||||
},
|
||||
save: {
|
||||
url: `/authority/role`,
|
||||
method: 'POST'
|
||||
},
|
||||
update: {
|
||||
url: `/authority/role`,
|
||||
method: 'PUT'
|
||||
},
|
||||
delete: {
|
||||
url: `/authority/role`,
|
||||
method: 'DELETE'
|
||||
},
|
||||
saveUserRole: {
|
||||
url: `/authority/role/user`,
|
||||
method: 'POST'
|
||||
},
|
||||
saveRoleAuthority: {
|
||||
url: `/authority/role/authority`,
|
||||
method: 'POST'
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/role/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
// formData: true,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
get (id) {
|
||||
return axiosApi({
|
||||
url: `/authority/role/${id}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
getDetails (id) {
|
||||
return axiosApi({
|
||||
url: `/authority/role/details/${id}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
check (code) {
|
||||
return axiosApi({
|
||||
url: `/authority/role/check/${code}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
saveUserRole (data) {
|
||||
return axiosApi({
|
||||
...apiList.saveUserRole,
|
||||
data
|
||||
})
|
||||
},
|
||||
findUserIdByRoleId (roleId) {
|
||||
return axiosApi({
|
||||
url: `/authority/role/user/${roleId}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
findAuthorityIdByRoleId (roleId) {
|
||||
return axiosApi({
|
||||
url: `/authority/role/authority/${roleId}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
saveRoleAuthority (data) {
|
||||
return axiosApi({
|
||||
...apiList.saveRoleAuthority,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
url: `/msgs/smsSendStatus/page`,
|
||||
method: 'POST'
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
url: `/msgs/smsTask/page`,
|
||||
method: 'POST'
|
||||
},
|
||||
save: {
|
||||
url: `/msgs/smsTask`,
|
||||
method: 'POST'
|
||||
},
|
||||
update: {
|
||||
url: `/msgs/smsTask`,
|
||||
method: 'PUT'
|
||||
},
|
||||
delete: {
|
||||
url: `/msgs/smsTask`,
|
||||
method: 'DELETE'
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/msgs/smsTask/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/msgs/smsTask/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/msgs/smsTask/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
get (id) {
|
||||
return axiosApi({
|
||||
url: `/msgs/smsTask/${id}`,
|
||||
method: 'GET'
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
url: `/msgs/smsTemplate/page`,
|
||||
method: 'POST'
|
||||
},
|
||||
save: {
|
||||
url: `/msgs/smsTemplate`,
|
||||
method: 'POST'
|
||||
},
|
||||
update: {
|
||||
url: `/msgs/smsTemplate`,
|
||||
method: 'PUT'
|
||||
},
|
||||
delete: {
|
||||
url: `/msgs/smsTemplate`,
|
||||
method: 'DELETE'
|
||||
},
|
||||
check: {
|
||||
url: `/msgs/smsTemplate/check`,
|
||||
method: 'GET'
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/msgs/smsTemplate/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/msgs/smsTemplate/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/msgs/smsTemplate/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
check (customCode) {
|
||||
const data = { customCode: customCode }
|
||||
return axiosApi({
|
||||
...apiList.check,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
url: `/authority/station/page`,
|
||||
method: 'POST'
|
||||
},
|
||||
save: {
|
||||
url: `/authority/station`,
|
||||
method: 'POST'
|
||||
},
|
||||
update: {
|
||||
url: `/authority/station`,
|
||||
method: 'PUT'
|
||||
},
|
||||
delete: {
|
||||
url: `/authority/station`,
|
||||
method: 'DELETE'
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/station/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/station/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/station/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/systemApi/page`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/systemApi`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/systemApi`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/systemApi`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/systemApi/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/systemApi/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/systemApi/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page(data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
scan(serviceId) {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: `/${serviceId}/systemApiScan`
|
||||
})
|
||||
},
|
||||
save(data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update(data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete(data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
preview(data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export(data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import(data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/tenant/page`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/tenant`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/tenant`
|
||||
},
|
||||
saveInit: {
|
||||
method: 'POST',
|
||||
url: `/authority/tenant/init`
|
||||
},
|
||||
remove: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/tenant/remove`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page(data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save(data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
saveInit(data) {
|
||||
return axiosApi({
|
||||
...apiList.saveInit,
|
||||
data
|
||||
})
|
||||
},
|
||||
update(data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
remove(data) {
|
||||
return axiosApi({
|
||||
...apiList.remove,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
import axiosApi from './AxiosApi.js'
|
||||
|
||||
const apiList = {
|
||||
page: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/page`
|
||||
},
|
||||
save: {
|
||||
method: 'POST',
|
||||
url: `/authority/user`
|
||||
},
|
||||
update: {
|
||||
method: 'PUT',
|
||||
url: `/authority/user`
|
||||
},
|
||||
updateBaseInfo: {
|
||||
method: 'PUT',
|
||||
url: `/authority/user/base`
|
||||
},
|
||||
avatar: {
|
||||
method: 'PUT',
|
||||
url: `/authority/user/avatar`
|
||||
},
|
||||
delete: {
|
||||
method: 'DELETE',
|
||||
url: `/authority/user`
|
||||
},
|
||||
reset: {
|
||||
method: 'GET',
|
||||
url: `/authority/user/reset`
|
||||
},
|
||||
updatePassword: {
|
||||
method: 'PUT',
|
||||
url: `/authority/user/password`
|
||||
},
|
||||
reload: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/reload`
|
||||
},
|
||||
preview: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/preview`
|
||||
},
|
||||
export: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/export`
|
||||
},
|
||||
import: {
|
||||
method: 'POST',
|
||||
url: `/authority/user/import`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
page (data) {
|
||||
return axiosApi({
|
||||
...apiList.page,
|
||||
data
|
||||
})
|
||||
},
|
||||
save (data) {
|
||||
return axiosApi({
|
||||
...apiList.save,
|
||||
data
|
||||
})
|
||||
},
|
||||
update (data) {
|
||||
return axiosApi({
|
||||
...apiList.update,
|
||||
data
|
||||
})
|
||||
},
|
||||
updateBaseInfo (data) {
|
||||
return axiosApi({
|
||||
...apiList.updateBaseInfo,
|
||||
data
|
||||
})
|
||||
},
|
||||
updatePassword (data) {
|
||||
return axiosApi({
|
||||
...apiList.updatePassword,
|
||||
data
|
||||
})
|
||||
},
|
||||
delete (data) {
|
||||
return axiosApi({
|
||||
...apiList.delete,
|
||||
data
|
||||
})
|
||||
},
|
||||
get (id) {
|
||||
return axiosApi({
|
||||
method: 'GET',
|
||||
url: `/authority/user/${id}`
|
||||
})
|
||||
},
|
||||
reset (data) {
|
||||
return axiosApi({
|
||||
...apiList.reset,
|
||||
data
|
||||
})
|
||||
},
|
||||
avatar (data) {
|
||||
return axiosApi({
|
||||
...apiList.avatar,
|
||||
data
|
||||
})
|
||||
},
|
||||
reload (userId) {
|
||||
return axiosApi({
|
||||
...apiList.reload,
|
||||
formData: true,
|
||||
data: { userId: userId }
|
||||
})
|
||||
},
|
||||
preview (data) {
|
||||
return axiosApi({
|
||||
...apiList.preview,
|
||||
data
|
||||
})
|
||||
},
|
||||
export (data) {
|
||||
return axiosApi({
|
||||
...apiList.export,
|
||||
responseType: "blob",
|
||||
data
|
||||
})
|
||||
},
|
||||
import (data) {
|
||||
return axiosApi({
|
||||
...apiList.import,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Executable → Regular
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 598 B |
Binary file not shown.
|
After Width: | Height: | Size: 610 B |
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="management-container-component">
|
||||
<Table :data="dataList" style="width: 100%">
|
||||
<Table :data="dataList.records" style="width: 100%" border>
|
||||
<table-column prop="name" label="店铺名称" />
|
||||
<table-column prop="code" label="店铺编码" />
|
||||
<table-column prop="duty" label="负责人" width="180" />
|
||||
@@ -37,6 +37,13 @@
|
||||
</template>
|
||||
</table-column>
|
||||
</Table>
|
||||
<pagination
|
||||
v-show="dataList.total > 0"
|
||||
:limit.sync="form.size"
|
||||
:page.sync="form.current"
|
||||
:total="Number(dataList.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<Dialog
|
||||
:center="true"
|
||||
title="查看商家"
|
||||
@@ -52,9 +59,10 @@
|
||||
<script>
|
||||
import Management from '@/api/Management.js'
|
||||
import { Table, TableColumn, Dialog } from 'element-ui'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import checkDialog from '@/components/Management/checkDialog'
|
||||
export default {
|
||||
components: { Table, TableColumn, Dialog, checkDialog },
|
||||
components: { Table, TableColumn, Dialog, checkDialog, Pagination },
|
||||
filters: {
|
||||
state(code) {
|
||||
const stateMap = {
|
||||
@@ -73,9 +81,9 @@ export default {
|
||||
},
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
type: Object,
|
||||
default() {
|
||||
return []
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -84,10 +92,17 @@ export default {
|
||||
checkVisible: false,
|
||||
checkData: {
|
||||
status: {}
|
||||
},
|
||||
form: {
|
||||
current: 1,
|
||||
size: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetch() {
|
||||
this.$emit('fetch', this.form)
|
||||
},
|
||||
checkRow(item) {
|
||||
this.checkVisible = true
|
||||
this.checkData = item
|
||||
@@ -148,4 +163,25 @@ export default {
|
||||
.management-container-component {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
/deep/ .el-table {
|
||||
th {
|
||||
background: #EEF3FF;
|
||||
color:#333333;
|
||||
font-size:16px;
|
||||
font-weight: 400;
|
||||
border-color: #E0E5EB;
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.cell {
|
||||
text-align: center;
|
||||
white-space: pre-line;/*保留换行符*/
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
</form-item>
|
||||
<form-item label="生效时限" prop="expireLimitYear">
|
||||
<form-item label="生效时限(年)" prop="expireLimitYear">
|
||||
<Input
|
||||
v-model="dataMap.expireLimitYear"
|
||||
readonly
|
||||
@@ -70,7 +70,7 @@
|
||||
</form-item>
|
||||
<form-item label="账号" prop="mobile">
|
||||
<Input
|
||||
v-model="dataMap.mobile"
|
||||
v-model="dataMap.account"
|
||||
readonly
|
||||
size="medium"
|
||||
maxlength="11"
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="common-tree">
|
||||
<el-tree
|
||||
:ref="treeRef"
|
||||
:data="treeData"
|
||||
:check-strictly="checkStrictly"
|
||||
show-checkbox
|
||||
:accordion="false"
|
||||
node-key="id"
|
||||
default-expand-all
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNodeMethod"
|
||||
@check-change="checkChange"
|
||||
@node-click="nodeClick"
|
||||
@current-change="currentChange"
|
||||
>
|
||||
<span
|
||||
slot-scope="{ data, node }"
|
||||
class="custom-tree-node"
|
||||
>
|
||||
<span style="margin-right: 15px;">{{ data.label }}</span>
|
||||
<slot
|
||||
:data="data"
|
||||
:node="node"
|
||||
></slot>
|
||||
<!-- <template v-if='data.id !== "0"'> -->
|
||||
<!-- <span class='ope-btn' title='添加' @click='modify("onAdd", data, node)'>
|
||||
<i class='el-icon-plus' />
|
||||
</span>
|
||||
<span class='ope-btn' title='修改' @click='modify("onEdit", data, node)'>
|
||||
<i class='el-icon-edit' />
|
||||
</span>
|
||||
<span
|
||||
class='ope-btn ope-btn-remove'
|
||||
title='删除'
|
||||
@click='modify("onDelete", data, node)'
|
||||
v-if='!data.children'
|
||||
>
|
||||
<i class='el-icon-delete' />
|
||||
</span>-->
|
||||
<!-- </template> -->
|
||||
</span>
|
||||
</el-tree>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
treeRef: {
|
||||
type: String,
|
||||
default: "treeRef"
|
||||
},
|
||||
treeData: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
checkStrictly: {
|
||||
type: Boolean,
|
||||
default () {
|
||||
return true
|
||||
}
|
||||
},
|
||||
opeBtns: {
|
||||
type: Array,
|
||||
default () {
|
||||
return ['add', 'edit', 'remove']
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
modify (type, data, node) {
|
||||
window.event.stopPropagation()
|
||||
this.$emit(type, data, node)
|
||||
},
|
||||
checkChange (data, checked, childrenChecked) {
|
||||
this.$emit('checkChange', data, checked, childrenChecked)
|
||||
},
|
||||
nodeClick (data, node, tree) {
|
||||
this.$emit('nodeClick', data, node, tree)
|
||||
},
|
||||
currentChange (data, node) {
|
||||
this.$emit('currentChange', data, node)
|
||||
},
|
||||
filterNodeMethod (value, data) {
|
||||
// reutrn this.$emit('filterNodeMethod', value, data, node)
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.common-tree {
|
||||
.el-tree-node__content {
|
||||
height: 28px;
|
||||
.custom-tree-node {
|
||||
font-size: 14px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
width: 100%;
|
||||
.status-item {
|
||||
top: 4px;
|
||||
}
|
||||
.tree-icon {
|
||||
vertical-align: middle;
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-el-drag-dialog :close-on-click-modal="false" :title="title"
|
||||
:type="type" :visible.sync="isVisible"
|
||||
:width="width" top="50px" @dragDialog="handleDrag"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="model" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="文件" prop="fileLength">
|
||||
<fileUpload
|
||||
ref="fileRef" :accept-size="acceptSize" :auto-upload="false"
|
||||
:limit="1" :accept="accept"
|
||||
:action="action" @fileLengthVaild="fileLengthVaild" @setId="setIdAndSubmit"
|
||||
>
|
||||
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
|
||||
<div slot="tip" class="el-upload__tip">文件不超过100MB</div>
|
||||
</fileUpload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button :disabled="disabled" plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import fileUpload from "@/components/ceres/fileUpload"
|
||||
|
||||
export default {
|
||||
name: 'CommonImport',
|
||||
directives: { elDragDialog, fileUpload },
|
||||
components: { fileUpload },
|
||||
props: {
|
||||
action: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
// 允许上传的文件大小 单位:字节
|
||||
acceptSize: {
|
||||
type: Number,
|
||||
default: 50 * 1024 * 1024
|
||||
},
|
||||
accept: {
|
||||
type: String,
|
||||
default: '.xls,.xlsx'
|
||||
},
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
model: this.initImport(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
fileLength: 0,
|
||||
disabled: false,
|
||||
rules: {
|
||||
fileLength: {
|
||||
required: true, trigger: "change",
|
||||
validator: (rule, value, callback) => {
|
||||
const vm = this
|
||||
if (vm.fileLength === 0) {
|
||||
callback(new Error("请上传文件"))
|
||||
} else if (vm.fileLength > 1) {
|
||||
callback(new Error("一次性只能上传1个文件"))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return this.$t('common.upload')
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted() {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initImport() {
|
||||
return {
|
||||
id: '',
|
||||
bizId: '',
|
||||
bizType: '',
|
||||
file: null,
|
||||
isSingle: false
|
||||
}
|
||||
},
|
||||
handleDrag() {
|
||||
},
|
||||
// 附件长度校验
|
||||
fileLengthVaild(data) {
|
||||
const vm = this
|
||||
vm.fileLength = data || 0
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
setModel(val) {
|
||||
const vm = this
|
||||
if (val) {
|
||||
vm.model = { ...val }
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.disabled = false
|
||||
this.model = this.initImport()
|
||||
this.$refs.fileRef.init({
|
||||
id: ""
|
||||
})
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
vm.disabled = true
|
||||
vm.$refs.fileRef.submitFile(this.model.id, this.model.bizId, this.model.bizType)
|
||||
},
|
||||
setIdAndSubmit(isUploadCompleted, response) {
|
||||
const vm = this
|
||||
if (isUploadCompleted) {
|
||||
vm.disabled = false
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
} else if (response && response['code'] === -9 && response['data']) {
|
||||
// 原本是想要下载数据,但存在一些问题
|
||||
// commonApi.export(this.exportErrorUrl, {failList: response['data']})
|
||||
// .then(response => {
|
||||
// downloadFile(response);
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,368 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
:ref="uploadRef"
|
||||
:accept="accept"
|
||||
:action="action"
|
||||
:auto-upload="autoUpload"
|
||||
:before-remove="beforeRemove"
|
||||
:class="isUpload === false ? 'hidebtn' : ''"
|
||||
:data="fileOtherData"
|
||||
:file-list="fileList"
|
||||
:headers="headers"
|
||||
:limit="limit"
|
||||
:multiple="multiple"
|
||||
:on-change="handleChange"
|
||||
:on-error="handleError"
|
||||
:on-exceed="handleExceed"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="handleRemove"
|
||||
class="upload-demo"
|
||||
>
|
||||
<el-button
|
||||
v-if="isUpload" size="small" type="primary"
|
||||
>点击上传</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import db from "@/utils/localstorage"
|
||||
import commonApi from "@/api/Common.js"
|
||||
import { copy } from '@/utils/utils'
|
||||
import { Base64 } from 'js-base64'
|
||||
|
||||
export default {
|
||||
name: "FileUpload",
|
||||
props: {
|
||||
uploadRef: {
|
||||
type: String,
|
||||
default: "file1"
|
||||
},
|
||||
// 是否多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否自动上传
|
||||
autoUpload: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否上传文件
|
||||
isUpload: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 最大允许上传个数
|
||||
limit: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 允许上传的文件类型
|
||||
accept: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
action: {
|
||||
type: String,
|
||||
default: `${process.env.VUE_APP_BASE_API}/file/attachment/upload`
|
||||
},
|
||||
// 允许上传的文件大小 单位:字节
|
||||
acceptSize: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 默认额外上传数据
|
||||
fileOtherData: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
id: null,
|
||||
bizId: "",
|
||||
bizType: "",
|
||||
isSingle: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 默认附件列表
|
||||
fileList: [],
|
||||
// 删除附件列表
|
||||
removeFileAry: [],
|
||||
// 新增附件列表
|
||||
addFileAry: [],
|
||||
// 上传成功的文件数
|
||||
successNum: 0,
|
||||
// 上传失败的文件数
|
||||
errorNum: 0,
|
||||
// 已上传的文件数
|
||||
uploadTotalNum: 0,
|
||||
// 是否上传失败
|
||||
isUploadError: false
|
||||
// action: `${process.env.VUE_APP_BASE_API}/file/attachment/upload`
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
headers() {
|
||||
return {
|
||||
token: 'Bearer ' + db.get("TOKEN", ""),
|
||||
tenant: db.get("TENANT", "") || "",
|
||||
Authorization: `Basic ${Base64.encode(`${process.env.VUE_APP_CLIENT_ID}:${process.env.VUE_APP_CLIENT_SECRET}`)}`
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 附件初始化
|
||||
init({ id, bizId, bizType, isSingle, isDetail }) {
|
||||
const vm = this
|
||||
vm.fileOtherData.bizId = bizId
|
||||
vm.fileOtherData.id = id || ""
|
||||
vm.fileOtherData.bizType = bizType
|
||||
vm.fileOtherData.isSingle = isSingle || false
|
||||
vm.fileList.length = 0
|
||||
vm.removeFileAry = []
|
||||
vm.addFileAry = []
|
||||
vm.$emit("fileLengthVaild", 0)
|
||||
if (isDetail) {
|
||||
vm.getAttachment()
|
||||
}
|
||||
vm.successNum = 0
|
||||
vm.errorNum = 0
|
||||
vm.uploadTotalNum = 0
|
||||
vm.$refs[vm.uploadRef].clearFiles()
|
||||
},
|
||||
|
||||
handleChange(file, fileList) {
|
||||
const vm = this
|
||||
if (file.response) {
|
||||
vm.uploadTotalNum += 1
|
||||
if (file.response.isSuccess) {
|
||||
vm.fileOtherData.bizId = file.response.data.bizId
|
||||
vm.successNum += 1
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
vm.$message({
|
||||
message: file.name + "上传失败,原因:<br/>" + file.response.msg,
|
||||
type: "error",
|
||||
dangerouslyUseHTMLString: true,
|
||||
showClose: true,
|
||||
duration: 10000,
|
||||
onClose: (msgs) => {
|
||||
copy(msgs['message'])
|
||||
vm.$message({
|
||||
message: "复制错误消息成功",
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
})
|
||||
}, 0)
|
||||
vm.isUploadError = false
|
||||
vm.errorNum += 1
|
||||
}
|
||||
vm.$emit("setId", vm.uploadTotalNum === fileList.length && vm.errorNum <= 0, file.response)
|
||||
} else {
|
||||
if (vm.acceptSize) {
|
||||
const isLtAcceptSize = file.size > vm.acceptSize
|
||||
|
||||
if (isLtAcceptSize) {
|
||||
setTimeout(() => {
|
||||
vm.$message.error(
|
||||
"只能上传" +
|
||||
vm.renderSize(vm.acceptSize) +
|
||||
"的文件!已为您过滤文件:" +
|
||||
file.name
|
||||
)
|
||||
}, 10)
|
||||
|
||||
fileList.forEach((item, index) => {
|
||||
if (item.uid === file.uid) {
|
||||
fileList.splice(index, 1)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (!vm.isUploadError) {
|
||||
vm.addFileAry.push(file.name)
|
||||
}
|
||||
vm.isUploadError = false
|
||||
}
|
||||
} else {
|
||||
if (!vm.isUploadError) {
|
||||
vm.addFileAry.push(file.name)
|
||||
}
|
||||
vm.isUploadError = false
|
||||
}
|
||||
vm.$emit("fileLengthVaild", vm.fileList.length + vm.addFileAry.length)
|
||||
}
|
||||
vm.$store.state.hasLoading = false
|
||||
},
|
||||
// 附件上传失败
|
||||
handleError() {
|
||||
const vm = this
|
||||
vm.$message.error("附件上传失败,请重试")
|
||||
vm.isUploadError = true
|
||||
vm.$store.state.hasLoading = false
|
||||
},
|
||||
renderSize(value) {
|
||||
if (value == null || value == "") {
|
||||
return "0 B"
|
||||
}
|
||||
const unitArr = new Array(
|
||||
"B",
|
||||
"KB",
|
||||
"MB",
|
||||
"GB",
|
||||
"TB",
|
||||
"PB",
|
||||
"EB",
|
||||
"ZB",
|
||||
"YB"
|
||||
)
|
||||
let index = 0
|
||||
const srcsize = parseFloat(value)
|
||||
index = Math.floor(Math.log(srcsize) / Math.log(1024))
|
||||
let size = srcsize / Math.pow(1024, index)
|
||||
size = size.toFixed(2)
|
||||
if (unitArr[index]) {
|
||||
return size + unitArr[index]
|
||||
}
|
||||
return "文件太大"
|
||||
},
|
||||
handlePreview(file) {
|
||||
if (file.bizId) {
|
||||
this.downLoadFile(file)
|
||||
}
|
||||
},
|
||||
beforeRemove(file) {
|
||||
return this.$confirm("确定移除" + file.name, "删除确认")
|
||||
},
|
||||
// 文件超出个数限制时的钩子
|
||||
handleExceed() {
|
||||
const vm = this
|
||||
vm.$message("当前最多允许上传" + vm.limit + "个文件")
|
||||
},
|
||||
// 删除附件列表
|
||||
handleRemove(file) {
|
||||
const vm = this
|
||||
if (file.bizId) {
|
||||
vm.removeFileAry.push(file.id)
|
||||
vm.fileList.map((item, index) => {
|
||||
if (item.name === file.name) {
|
||||
vm.fileList.splice(index, 1)
|
||||
return false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
vm.addFileAry.map((item, index) => {
|
||||
if (item === file.name) {
|
||||
vm.addFileAry.splice(index, 1)
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
vm.$emit("fileLengthVaild", vm.fileList.length + vm.addFileAry.length)
|
||||
},
|
||||
// 服务器删除附件
|
||||
async deleteAttachment() {
|
||||
const vm = this
|
||||
const res = await commonApi.deleteAttachment({
|
||||
ids: vm.removeFileAry
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.data.code !== 0) {
|
||||
vm.$message(res.data.msg)
|
||||
} else {
|
||||
vm.removeFileAry = []
|
||||
}
|
||||
}
|
||||
},
|
||||
// 查询附件
|
||||
async getAttachment() {
|
||||
const vm = this
|
||||
const res = await commonApi.getAttachment({
|
||||
bizIds: vm.fileOtherData.bizId,
|
||||
bizTypes: vm.fileOtherData.bizType
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.data.code === 0) {
|
||||
if (res.data.data.length > 0) {
|
||||
const data = res.data.data[0].list
|
||||
data.map(item => {
|
||||
item.name = item.submittedFileName
|
||||
})
|
||||
vm.fileList = data
|
||||
vm.$emit("fileLengthVaild", vm.fileList.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 查询附件
|
||||
async getAttachmentByArr(bizIds, bizTypes) {
|
||||
const vm = this
|
||||
const res = await commonApi.getAttachment({
|
||||
bizIds: bizIds,
|
||||
bizTypes: bizTypes
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.data.code === 0) {
|
||||
if (res.data.data.length > 0) {
|
||||
const data = res.data.data[0].list
|
||||
data.map(item => {
|
||||
item.name = item.submittedFileName
|
||||
})
|
||||
vm.fileList = data
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 返回附件新增及删除数组长度
|
||||
handleBack() {
|
||||
const vm = this
|
||||
return {
|
||||
addLength: vm.addFileAry.length,
|
||||
removeLength: vm.removeFileAry.length
|
||||
}
|
||||
},
|
||||
// 附件上传服务器触发方法
|
||||
submitFile(id, bizId, bizType, tagId) {
|
||||
const vm = this
|
||||
vm.fileOtherData.id = id
|
||||
if (bizId) {
|
||||
vm.fileOtherData.bizId = bizId
|
||||
vm.isUpload = true
|
||||
}
|
||||
if (tagId) {
|
||||
vm.fileOtherData.tagId = tagId
|
||||
}
|
||||
vm.fileOtherData.bizType = bizType
|
||||
if (vm.limitType(vm.$refs[vm.uploadRef].uploadFiles).length) {
|
||||
return vm.$message.error('只能上传jpg/png/mp4格式的文件')
|
||||
}
|
||||
vm.$refs[vm.uploadRef].submit()
|
||||
vm.addFileAry = []
|
||||
},
|
||||
// 附件下载
|
||||
async downLoadFile(data) {
|
||||
const link = document.createElement("a")
|
||||
link.href = data.url
|
||||
link.download = data.name
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(link.href)
|
||||
},
|
||||
// 限制上传类型
|
||||
limitType(arr) {
|
||||
return arr.filter(item => {
|
||||
const t = item.raw.type
|
||||
return t.indexOf('image') === -1 && t.indexOf('video') === -1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.hidebtn .el-upload {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
:ref="uploadRef"
|
||||
:accept="accept"
|
||||
:action="action"
|
||||
:auto-upload="autoUpload"
|
||||
:before-upload="beforeUpload"
|
||||
:class="{ limit: showUploadBtn }"
|
||||
:data="fileOtherData"
|
||||
:file-list="imgFileList"
|
||||
:headers="headers"
|
||||
:limit="limit"
|
||||
:multiple="multiple"
|
||||
:on-change="handleChange"
|
||||
:on-error="handleError"
|
||||
:on-exceed="handleExceed"
|
||||
:on-remove="handleRemove"
|
||||
:show-file-list="showFileList"
|
||||
class="avatar-uploader"
|
||||
list-type="picture-card"
|
||||
>
|
||||
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||
<i v-else class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible">
|
||||
<img :src="dialogImageUrl" alt width="100%" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import db from "@/utils/localstorage"
|
||||
import commonApi from "@/api/Common.js"
|
||||
import { Base64 } from 'js-base64'
|
||||
export default {
|
||||
props: {
|
||||
uploadRef: {
|
||||
type: String,
|
||||
default: "file1"
|
||||
},
|
||||
// 是否多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否自动上传
|
||||
autoUpload: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否显示上传列表
|
||||
showFileList: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 最大允许上传个数
|
||||
limit: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 允许上传的文件类型
|
||||
accept: {
|
||||
type: String,
|
||||
default: "image/jpeg, image/gif, image/png, image/bmp"
|
||||
},
|
||||
// 允许上传的文件大小 单位:字节
|
||||
acceptSize: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 默认额外上传数据
|
||||
fileOtherData: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
bizId: "",
|
||||
bizType: "",
|
||||
isSingle: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imageUrl: "",
|
||||
dialogImageUrl: "",
|
||||
dialogVisible: false,
|
||||
disabled: true,
|
||||
// 默认附件列表
|
||||
imgFileList: [],
|
||||
// 删除附件列表
|
||||
removeFileAry: [],
|
||||
// 新增附件列表
|
||||
addFileAry: [],
|
||||
// 是否上传失败
|
||||
isUploadError: false,
|
||||
fileLength: 0,
|
||||
action: `${process.env.VUE_APP_BASE_API}/file/attachment/upload`
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showUploadBtn() {
|
||||
return (
|
||||
this.showFileList &&
|
||||
this.addFileAry.length + this.imgFileList.length === this.limit
|
||||
)
|
||||
},
|
||||
headers() {
|
||||
return {
|
||||
token: 'Bearer ' + db.get("TOKEN", ""),
|
||||
tenant: db.get("TENANT", "") || "",
|
||||
Authorization: `Basic ${Base64.encode(`${process.env.VUE_APP_CLIENT_ID}:${process.env.VUE_APP_CLIENT_SECRET}`)}`
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 附件初始化
|
||||
init({ bizId, bizType, imageUrl, isSingle, isDetail }) {
|
||||
const vm = this
|
||||
vm.fileOtherData.bizId = bizId
|
||||
vm.fileOtherData.bizType = bizType
|
||||
vm.fileOtherData.isSingle = isSingle || false
|
||||
// vm.imgFileList = []
|
||||
vm.imgFileList.length = 0
|
||||
vm.removeFileAry = []
|
||||
vm.addFileAry = []
|
||||
vm.imageUrl = imageUrl
|
||||
vm.isUploadError = false
|
||||
if (isDetail) {
|
||||
vm.getAttachment()
|
||||
}
|
||||
},
|
||||
// 附件上传前触发
|
||||
beforeUpload() {
|
||||
const vm = this
|
||||
vm.$store.state.hasLoading = true
|
||||
},
|
||||
// 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
|
||||
handleChange(file, fileList) {
|
||||
const vm = this
|
||||
if (file.response) {
|
||||
if (file.response.isSuccess) {
|
||||
const remoteFile = file.response.data
|
||||
vm.fileOtherData.bizId = remoteFile.bizId
|
||||
vm.imageUrl = remoteFile.url
|
||||
vm.$emit("setId", remoteFile.bizId, remoteFile.url)
|
||||
} else {
|
||||
vm.$message.error(file.response.msg)
|
||||
vm.isUploadError = false
|
||||
}
|
||||
} else {
|
||||
if (vm.acceptSize) {
|
||||
const isLtAcceptSize = file.size > vm.acceptSize
|
||||
if (isLtAcceptSize) {
|
||||
setTimeout(() => {
|
||||
vm.$message.error(
|
||||
"只能上传" +
|
||||
vm.renderSize(vm.acceptSize) +
|
||||
"的文件!已为您过滤文件:" +
|
||||
file.name
|
||||
)
|
||||
}, 10)
|
||||
|
||||
fileList.forEach((item, index) => {
|
||||
if (item.uid === file.uid) {
|
||||
fileList.splice(index, 1)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (!vm.isUploadError) {
|
||||
vm.addFileAry.push(file.name)
|
||||
}
|
||||
vm.isUploadError = false
|
||||
}
|
||||
}
|
||||
}
|
||||
vm.$store.state.hasLoading = false
|
||||
},
|
||||
renderSize(value) {
|
||||
if (value == null || value == "") {
|
||||
return "0 B"
|
||||
}
|
||||
const unitArr = new Array(
|
||||
"B",
|
||||
"KB",
|
||||
"MB",
|
||||
"GB",
|
||||
"TB",
|
||||
"PB",
|
||||
"EB",
|
||||
"ZB",
|
||||
"YB"
|
||||
)
|
||||
let index = 0
|
||||
const srcsize = parseFloat(value)
|
||||
index = Math.floor(Math.log(srcsize) / Math.log(1024))
|
||||
let size = srcsize / Math.pow(1024, index)
|
||||
size = size.toFixed(2)
|
||||
if (unitArr[index]) {
|
||||
return size + unitArr[index]
|
||||
}
|
||||
return "文件太大"
|
||||
},
|
||||
// 附件上传失败
|
||||
handleError() {
|
||||
const vm = this
|
||||
vm.$message.error("附件上传失败,请重试")
|
||||
vm.isUploadError = true
|
||||
vm.$store.state.hasLoading = false
|
||||
if (!vm.showFileList) {
|
||||
vm.imageUrl = ""
|
||||
}
|
||||
},
|
||||
// 查询附件
|
||||
async getAttachment() {
|
||||
const vm = this
|
||||
const res = await commonApi.getAttachment({
|
||||
bizIds: vm.fileOtherData.bizId,
|
||||
bizTypes: vm.fileOtherData.bizType
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.data.code === 0) {
|
||||
if (res.data.data.length > 0) {
|
||||
const data = res.data.data[0].list
|
||||
data.map(item => {
|
||||
item.name = item.submittedFileName
|
||||
if (!vm.showFileList) {
|
||||
vm.imageUrl = item.url
|
||||
}
|
||||
})
|
||||
vm.imgFileList = data
|
||||
vm.$emit("fileLengthVaild", vm.imgFileList.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 删除附件回调
|
||||
handleRemove(file) {
|
||||
const vm = this
|
||||
if (file.bizId) {
|
||||
vm.removeFileAry.push(file.id)
|
||||
vm.imgFileList.map((item, index) => {
|
||||
if (item.bizId === file.bizId) {
|
||||
vm.imgFileList.splice(index, 1)
|
||||
return false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
vm.addFileAry.map((item, index) => {
|
||||
if (item === file.name) {
|
||||
vm.addFileAry.splice(index, 1)
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
// 文件超出个数限制时的钩子
|
||||
handleExceed() {
|
||||
const vm = this
|
||||
vm.$message("当前最多允许上传" + vm.limit + "张图片")
|
||||
},
|
||||
// 返回附件新增及删除数组长度
|
||||
handleBack() {
|
||||
const vm = this
|
||||
return {
|
||||
addLength: vm.addFileAry.length,
|
||||
removeLength: vm.removeFileAry.length
|
||||
}
|
||||
},
|
||||
// 服务器删除附件
|
||||
async deleteAttachment() {
|
||||
const vm = this
|
||||
const res = await commonApi.deleteAttachment({
|
||||
ids: vm.removeFileAry
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.data.code !== 0) {
|
||||
vm.$message(res.data.msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 附件上传服务器触发方法
|
||||
submitFile(bizId, bizType, isSingle) {
|
||||
const vm = this
|
||||
vm.fileOtherData.bizId = bizId
|
||||
vm.fileOtherData.bizType = bizType
|
||||
vm.fileOtherData.isSingle = isSingle
|
||||
if (!vm.showFileList) {
|
||||
const length = vm.$refs[vm.uploadRef].uploadFiles.length - 1
|
||||
vm.$refs[vm.uploadRef].uploadFiles = [
|
||||
vm.$refs[vm.uploadRef].uploadFiles[length]
|
||||
]
|
||||
vm.imgFileList.map(item => {
|
||||
vm.removeFileAry.push(item.id)
|
||||
})
|
||||
if (vm.imgFileList.length > 0) {
|
||||
vm.deleteAttachment()
|
||||
}
|
||||
}
|
||||
vm.$refs[vm.uploadRef].submit()
|
||||
vm.$store.state.hasLoading = false
|
||||
vm.addFileAry = []
|
||||
},
|
||||
// 服务器删除附件
|
||||
async deleteAttachmentByIds(ids) {
|
||||
const vm = this
|
||||
const res = await commonApi.deleteAttachment({
|
||||
ids: ids
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.data.code !== 0) {
|
||||
vm.$message(res.data.msg)
|
||||
} else {
|
||||
vm.removeFileAry = []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
/deep/.el-form-item__content {
|
||||
line-height: 0;
|
||||
}
|
||||
/deep/.el-upload-list--picture-card .el-upload-list__item {
|
||||
margin: 0 8px 0 0;
|
||||
}
|
||||
/deep/.el-upload--picture-card,
|
||||
/deep/.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
.limit {
|
||||
/deep/.el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+12
@@ -3,6 +3,10 @@ import 'dragula/dist/dragula.min.css'
|
||||
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
|
||||
import Element from 'element-ui'
|
||||
import './styles/element-variables.scss'
|
||||
import Viewer from 'v-viewer'
|
||||
import 'viewerjs/dist/viewer.css'
|
||||
import preview from 'vue-photo-preview'
|
||||
import 'vue-photo-preview/dist/skin.css'
|
||||
|
||||
// vue-quill-editor css
|
||||
import 'quill/dist/quill.core.css'
|
||||
@@ -33,6 +37,14 @@ Plugins.map((plugin) => {
|
||||
Vue.use(plugin)
|
||||
})
|
||||
|
||||
Vue.use(preview)
|
||||
Vue.use(Viewer)
|
||||
Viewer.setDefaults({
|
||||
Options: { "inline": true, "button": true, "navbar": true, "title": true, "toolbar": true,
|
||||
"tooltip": true, "movable": true, "zoomable": true, "rotatable": true, "scalable": true, "transition": true,
|
||||
"fullscreen": true, "keyboard": true, "url": "data-source" }
|
||||
})
|
||||
|
||||
Vue.use(Element, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
|
||||
@@ -149,10 +149,56 @@ const constRouter = [
|
||||
title: '保证金',
|
||||
affix: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/finance/overview',
|
||||
component: () => import('@/views/finance/overview/index'),
|
||||
meta: {
|
||||
title: '财务概况',
|
||||
affix: true
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/after-sale-service',
|
||||
component: Layout,
|
||||
name: '售后处理',
|
||||
children: [
|
||||
{
|
||||
path: '/after-sale-service',
|
||||
component: () => import('@/views/after-sale-service/index'),
|
||||
meta: {
|
||||
title: '售后处理',
|
||||
affix: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/after-sale-service/details',
|
||||
component: () => import('@/views/after-sale-service/details/index'),
|
||||
meta: {
|
||||
title: '售后详情',
|
||||
affix: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/menu',
|
||||
component: Layout,
|
||||
name: '菜单',
|
||||
children: [
|
||||
{
|
||||
path: '/menu/empower',
|
||||
component: () => import('@/views/menu/empower/index'),
|
||||
meta: {
|
||||
title: '菜单赋权',
|
||||
affix: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
component: Layout,
|
||||
@@ -184,6 +230,262 @@ const constRouter = [
|
||||
meta: { title: 'page404', noCache: true }
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"sortValue": 1,
|
||||
children: [{
|
||||
"sortValue": 0,
|
||||
path: "/user/org",
|
||||
name: "组织管理",
|
||||
component: resolve => require(['@/views/ceres/user/org/Index'], resolve),
|
||||
meta: {
|
||||
"title": "组织管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 1,
|
||||
path: "/user/station",
|
||||
name: "岗位管理",
|
||||
component: resolve => require(['@/views/ceres/user/station/Index'], resolve),
|
||||
meta: {
|
||||
"title": "岗位管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
path: "/user/user",
|
||||
name: "用户管理",
|
||||
component: resolve => require(['@/views/ceres/user/user/Index'], resolve),
|
||||
meta: {
|
||||
"title": "用户管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
path: "/user",
|
||||
name: "用户中心",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "用户中心",
|
||||
"icon": "el-icon-user-solid",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}, {
|
||||
"sortValue": 10,
|
||||
children: [{
|
||||
"sortValue": 1,
|
||||
path: "/auth/role",
|
||||
name: "角色管理",
|
||||
component: resolve => require(['@/views/ceres/auth/role/Index'], resolve),
|
||||
meta: {
|
||||
"title": "角色管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
path: "/auth/user",
|
||||
name: "菜单配置",
|
||||
component: resolve => require(['@/views/ceres/auth/menu/Index'], resolve),
|
||||
meta: {
|
||||
"title": "菜单配置",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
path: "/auth",
|
||||
name: "权限管理",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "权限管理",
|
||||
"icon": "el-icon-lock",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}, {
|
||||
"sortValue": 12,
|
||||
children: [{
|
||||
"sortValue": 1,
|
||||
path: "/developer/application",
|
||||
name: "应用管理",
|
||||
component: resolve => require(['@/views/ceres/developer/application/Index'], resolve),
|
||||
meta: {
|
||||
"title": "应用管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
path: "/developer/systemApi",
|
||||
name: "接口查询",
|
||||
component: resolve => require(['@/views/ceres/developer/systemApi/Index'], resolve),
|
||||
meta: {
|
||||
"title": "接口查询",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 3,
|
||||
path: "/developer/optLog",
|
||||
name: "操作日志",
|
||||
component: resolve => require(['@/views/ceres/developer/optLog/Index'], resolve),
|
||||
meta: {
|
||||
"title": "操作日志",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 4,
|
||||
path: "/developer/loginLog",
|
||||
name: "登录日志",
|
||||
component: resolve => require(['@/views/ceres/developer/loginLog/Index'], resolve),
|
||||
meta: {
|
||||
"title": "登录日志",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 5,
|
||||
path: "/developer/db",
|
||||
name: "数据库监控",
|
||||
component: resolve => require(['@/views/ceres/developer/db/Index'], resolve),
|
||||
meta: {
|
||||
"title": "数据库监控",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 6,
|
||||
path: "http://127.0.0.1:8760/api/gate/doc.html",
|
||||
name: "接口文档",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "接口文档",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 7,
|
||||
path: "http://127.0.0.1:8848/nacos",
|
||||
name: "注册&配置中心",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "注册&配置中心",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 8,
|
||||
path: "http://www.baidu.com",
|
||||
name: "缓存监控",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "缓存监控",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 10,
|
||||
path: "http://127.0.0.1:8767/ceres-jobs-server",
|
||||
name: "定时调度中心",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "定时调度中心",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 11,
|
||||
path: "http://127.0.0.1:8772/zipkin",
|
||||
name: "链路调用监控",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "链路调用监控",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
path: "/developer",
|
||||
name: "开发者管理",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "开发者管理",
|
||||
"icon": "el-icon-user-solid",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}, {
|
||||
"sortValue": 13,
|
||||
children: [{
|
||||
"sortValue": 1,
|
||||
path: "/msgs/sendMsgs",
|
||||
name: "消息推送",
|
||||
component: resolve => require(['@/views/ceres/msgs/sendMsgs/Index'], resolve),
|
||||
meta: {
|
||||
"title": "消息推送",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
path: "/msgs/myMsgs",
|
||||
name: "我的消息",
|
||||
component: resolve => require(['@/views/ceres/msgs/myMsgs/Index'], resolve),
|
||||
meta: {
|
||||
"title": "我的消息",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
path: "/msgs",
|
||||
name: "消息中心",
|
||||
component: Layout,
|
||||
meta: {
|
||||
"title": "消息中心",
|
||||
"icon": "el-icon-chat-line-square",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -93,8 +93,298 @@ export default {
|
||||
title: '保证金',
|
||||
icon: 'el-icon-money'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/finance/overview',
|
||||
name: '财务概况',
|
||||
meta: {
|
||||
title: '财务概况',
|
||||
icon: 'el-icon-pie-chart'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/after-sale-service',
|
||||
meta: {
|
||||
title: '售后处理',
|
||||
icon: 'el-icon-service'
|
||||
},
|
||||
children: []
|
||||
},
|
||||
{
|
||||
path: '/menu',
|
||||
meta: {
|
||||
title: '菜单',
|
||||
icon: 'el-icon-menu'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/menu/empower',
|
||||
name: '菜单赋权',
|
||||
meta: {
|
||||
title: '菜单赋权',
|
||||
icon: ''
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sortValue": 1,
|
||||
"children": [{
|
||||
"sortValue": 0,
|
||||
"path": "/user/org",
|
||||
"name": "组织管理",
|
||||
"component": "ceres/user/org/Index",
|
||||
"meta": {
|
||||
"title": "组织管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 1,
|
||||
"path": "/user/station",
|
||||
"name": "岗位管理",
|
||||
"component": "ceres/user/station/Index",
|
||||
"meta": {
|
||||
"title": "岗位管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
"path": "/user/user",
|
||||
"name": "用户管理",
|
||||
"component": "ceres/user/user/Index",
|
||||
"meta": {
|
||||
"title": "用户管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
"path": "/user",
|
||||
"name": "用户中心",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "用户中心",
|
||||
"icon": "el-icon-user-solid",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}, {
|
||||
"sortValue": 10,
|
||||
"children": [{
|
||||
"sortValue": 1,
|
||||
"path": "/auth/role",
|
||||
"name": "角色管理",
|
||||
"component": "ceres/auth/role/Index",
|
||||
"meta": {
|
||||
"title": "角色管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
"path": "/auth/user",
|
||||
"name": "菜单配置",
|
||||
"component": "ceres/auth/menu/Index",
|
||||
"meta": {
|
||||
"title": "菜单配置",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
"path": "/auth",
|
||||
"name": "权限管理",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "权限管理",
|
||||
"icon": "el-icon-lock",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}, {
|
||||
"sortValue": 12,
|
||||
"children": [{
|
||||
"sortValue": 1,
|
||||
"path": "/developer/application",
|
||||
"name": "应用管理",
|
||||
"component": "ceres/developer/application/Index",
|
||||
"meta": {
|
||||
"title": "应用管理",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
"path": "/developer/systemApi",
|
||||
"name": "接口查询",
|
||||
"component": "ceres/developer/systemApi/Index",
|
||||
"meta": {
|
||||
"title": "接口查询",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 3,
|
||||
"path": "/developer/optLog",
|
||||
"name": "操作日志",
|
||||
"component": "ceres/developer/optLog/Index",
|
||||
"meta": {
|
||||
"title": "操作日志",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 4,
|
||||
"path": "/developer/loginLog",
|
||||
"name": "登录日志",
|
||||
"component": "ceres/developer/loginLog/Index",
|
||||
"meta": {
|
||||
"title": "登录日志",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 5,
|
||||
"path": "/developer/db",
|
||||
"name": "数据库监控",
|
||||
"component": "ceres/developer/db/Index",
|
||||
"meta": {
|
||||
"title": "数据库监控",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 6,
|
||||
"path": "http://127.0.0.1:8760/api/gate/doc.html",
|
||||
"name": "接口文档",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "接口文档",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 7,
|
||||
"path": "http://127.0.0.1:8848/nacos",
|
||||
"name": "注册&配置中心",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "注册&配置中心",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 8,
|
||||
"path": "http://www.baidu.com",
|
||||
"name": "缓存监控",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "缓存监控",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 10,
|
||||
"path": "http://127.0.0.1:8767/ceres-jobs-server",
|
||||
"name": "定时调度中心",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "定时调度中心",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 11,
|
||||
"path": "http://127.0.0.1:8772/zipkin",
|
||||
"name": "链路调用监控",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "链路调用监控",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
"path": "/developer",
|
||||
"name": "开发者管理",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "开发者管理",
|
||||
"icon": "el-icon-user-solid",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}, {
|
||||
"sortValue": 13,
|
||||
"children": [{
|
||||
"sortValue": 1,
|
||||
"path": "/msgs/sendMsgs",
|
||||
"name": "消息推送",
|
||||
"component": "ceres/msgs/sendMsgs/Index",
|
||||
"meta": {
|
||||
"title": "消息推送",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}, {
|
||||
"sortValue": 2,
|
||||
"path": "/msgs/myMsgs",
|
||||
"name": "我的消息",
|
||||
"component": "ceres/msgs/myMsgs/Index",
|
||||
"meta": {
|
||||
"title": "我的消息",
|
||||
"icon": "",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": false
|
||||
}],
|
||||
"path": "/msgs",
|
||||
"name": "消息中心",
|
||||
"component": "Layout",
|
||||
"meta": {
|
||||
"title": "消息中心",
|
||||
"icon": "el-icon-chat-line-square",
|
||||
"breadcrumb": true
|
||||
},
|
||||
"hidden": false,
|
||||
"alwaysShow": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 判断终端以及浏览器
|
||||
* userAgent string User-Agent信息
|
||||
*/
|
||||
export const readUserAgent = ua => {
|
||||
const data = {
|
||||
terminal: '',
|
||||
browser: '',
|
||||
terminalType: {}
|
||||
}
|
||||
data.terminalType = {
|
||||
trident: ua.indexOf('Trident') > -1, // IE内核
|
||||
presto: ua.indexOf('Presto') > -1, // opera内核
|
||||
webKit: ua.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
|
||||
gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, // 火狐内核
|
||||
mobile: !!ua.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
|
||||
ios: !!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
|
||||
android: ua.indexOf('Android') > -1 || ua.indexOf('Adr') > -1, // android终端
|
||||
iPhone: ua.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器
|
||||
iPad: ua.indexOf('iPad') > -1, // 是否iPad
|
||||
webApp: ua.indexOf('Safari') === -1, // 是否web应该程序,没有头部与底部
|
||||
weixin: ua.indexOf('MicroMessenger') > -1, // 是否微信 (2015-01-22新增)
|
||||
qq: ua.match(/\sQQ/i) === ' qq' // 是否QQ
|
||||
}
|
||||
if (
|
||||
data.terminalType.ios ||
|
||||
data.terminalType.iPhone ||
|
||||
data.terminalType.iPad
|
||||
) {
|
||||
data.terminal = '苹果'
|
||||
} else if (data.terminalType.android) {
|
||||
data.terminal = '安卓'
|
||||
} else {
|
||||
data.terminal = 'PC'
|
||||
}
|
||||
if (/msie/i.test(ua) && !/opera/.test(ua)) {
|
||||
data.browser = 'IE'
|
||||
} else if (/firefox/i.test(ua)) {
|
||||
data.browser = 'Firefox'
|
||||
} else if (/chrome/i.test(ua) && /webkit/i.test(ua) && /mozilla/i.test(ua)) {
|
||||
data.browser = 'Chrome'
|
||||
} else if (/opera/i.test(ua)) {
|
||||
data.browser = 'Opera'
|
||||
} else if (/iPad/i.test(ua)) {
|
||||
data.browser = 'iPad'
|
||||
} else if (
|
||||
/webkit/i.test(ua) &&
|
||||
!(/chrome/i.test(ua) && /webkit/i.test(ua) && /mozilla/i.test(ua))
|
||||
) {
|
||||
data.browser = 'Safari'
|
||||
} else {
|
||||
data.browser = '未知'
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 格式化文件大小 单位:B、KB、MB、GB
|
||||
const renderSize = value => {
|
||||
if (value == null || value == '') {
|
||||
return "0 B"
|
||||
}
|
||||
var unitArr = new Array("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
|
||||
var index = 0
|
||||
var srcsize = parseFloat(value)
|
||||
index = Math.floor(Math.log(srcsize) / Math.log(1024))
|
||||
var size = srcsize / Math.pow(1024, index)
|
||||
size = size.toFixed(2)
|
||||
if (unitArr[index]) {
|
||||
return size + unitArr[index]
|
||||
}
|
||||
return '文件太大'
|
||||
}
|
||||
|
||||
const convertEnum = obj => {
|
||||
const list = []
|
||||
if (obj) {
|
||||
for (const key in obj) {
|
||||
list.push({
|
||||
text: obj[key],
|
||||
value: key
|
||||
})
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
const copy = msg => {
|
||||
if (msg) {
|
||||
const oInput = document.createElement('input') // 创建一个隐藏input(重要!)
|
||||
oInput.value = msg // 赋值
|
||||
document.body.appendChild(oInput)
|
||||
oInput.select() // 选择对象
|
||||
document.execCommand("Copy") // 执行浏览器复制命令
|
||||
oInput.className = 'oInput'
|
||||
oInput.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
export { renderSize, convertEnum, copy }
|
||||
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="dialog.allow" class="allow">
|
||||
<h1>建议联系商家,由商家操作同意退款。</h1>
|
||||
<p>
|
||||
若你同意售后,客户申请的类型为仅退款时,将自动从商家账户退款给买家 若客户申请的类型为退款退货时,本售后将转为待买家退回物品的状态,有可能被商家拒收
|
||||
</p>
|
||||
</div>
|
||||
<div v-else class="refuse">
|
||||
<p>拒绝售后,本售后将自动关闭,但买家有权再次发起。</p>
|
||||
</div>
|
||||
|
||||
<el-form label-width="120px" :model="form">
|
||||
<el-form-item label="备注内容">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请填写相关内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="btn_list">
|
||||
<el-button type="primary">{{ dialog.btnName }}</el-button>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
dialog: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
remark: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
cancel() {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
h1 {
|
||||
font-size:24px;
|
||||
font-weight:500;
|
||||
color:rgba(51,51,51,1);
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
margin: 30px auto;
|
||||
}
|
||||
p {
|
||||
font-size:16px;
|
||||
color:rgba(51,51,51,1);
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
margin: 30px auto;
|
||||
}
|
||||
|
||||
.btn_list {
|
||||
width: 200px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
/deep/ .el-textarea {
|
||||
width: 100%;
|
||||
textarea {
|
||||
min-height: 150px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div class="store_info_page">
|
||||
<p v-for="(item,index) in storeInfo" :key="index">
|
||||
<span>{{ item.name }}:</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeInfo: [
|
||||
{ name: '下单账户', value: '和理智上', field: '' },
|
||||
{ name: '注册时间', value: '2020-06-30', field: '' },
|
||||
{ name: '手机号', value: '13966781258', field: '' },
|
||||
{ name: '订单总数', value: '12个', field: '' },
|
||||
{ name: '售后单数', value: '5个', field: '' },
|
||||
{ name: '售后成功率', value: '68%', field: '' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.store_info_page {
|
||||
padding: 20px 10%;
|
||||
overflow: hidden;
|
||||
p {
|
||||
width: 50%;
|
||||
float: left;
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
display: inline-block;
|
||||
&:nth-of-type(1) {
|
||||
width:130px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
color:#666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div class="logistics_info">
|
||||
<div class="logistics_com">
|
||||
<p v-for="(item,index) in list" :key="index">
|
||||
<span>{{ item.name }}:</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="logistics_status">
|
||||
<div>物流信息:</div>
|
||||
<div>
|
||||
<p v-for="(item,index) in logisticsList" :key="index">
|
||||
<span>{{ item.time }}</span>
|
||||
<span>{{ item.status }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
{ name: '物流公司', value: '中通', field: '' },
|
||||
{ name: '运单号', value: '123123', field: '' }
|
||||
],
|
||||
logisticsList: [
|
||||
{ time: '2020/12/20 15:20:23', status: '正在派件', field: '' },
|
||||
{ time: '2020/12/20 15:20:23', status: '已从廊坊发货', field: '' },
|
||||
{ time: ' 2020/12/20 15:20:23', status: '已到达目的地', field: '' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.logistics_info {
|
||||
padding: 20px 10%;
|
||||
.logistics_com {
|
||||
overflow: hidden;
|
||||
margin-bottom: 30px;
|
||||
p {
|
||||
width: 50%;
|
||||
float: left;
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
display: inline-block;
|
||||
&:nth-of-type(1) {
|
||||
width:80px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
color:#666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.logistics_status {
|
||||
overflow: hidden;
|
||||
div {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
float: left;
|
||||
&:nth-of-type(1) {
|
||||
width:80px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
width: calc(80% - 80px);
|
||||
color:#666666;
|
||||
p {
|
||||
margin: 0;
|
||||
margin-bottom: 20px;
|
||||
span {
|
||||
display: inline-block;
|
||||
&:nth-of-type(2) {
|
||||
margin-left: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="order_info_page">
|
||||
<div class="order_info">
|
||||
<p v-for="(item,index) in orderInfo" :key="index">
|
||||
<span>{{ item.name }}:</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="detail_title">
|
||||
商品信息
|
||||
</div>
|
||||
<div
|
||||
v-for="(item,index) in shopList"
|
||||
:key="index"
|
||||
class="goods_list"
|
||||
>
|
||||
<div class="good_details">
|
||||
<ul>
|
||||
<li>
|
||||
<img :src="item.skuImg" />
|
||||
</li>
|
||||
<li>
|
||||
<p>{{ item.productName }}</p>
|
||||
<p>{{ item.skuNameStr }}</p>
|
||||
<p>SKU: {{ item.skuId }}</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>¥{{ item.sellPrice*item.buyNum }}</p>
|
||||
<p>¥{{ `${item.sellPrice}*${item.buyNum}` }}</p>
|
||||
</li>
|
||||
<li> ¥{{ item.salePrice * item.buyNum }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="total">
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li> </li>
|
||||
<li>
|
||||
<p><span>订单总金额</span> <span>¥240</span> </p>
|
||||
<p><span>物流费用</span> <span>¥40</span></p>
|
||||
<p><span>平台优惠(618活动)</span> <span>-¥100</span></p>
|
||||
<p><span>实付</span> <span>¥180</span></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderInfo: [
|
||||
{ name: '订单ID', value: '542543543', field: '' },
|
||||
{ name: '支付单号', value: '12353563', field: '' },
|
||||
{ name: '支付状态', value: '待发货', field: '' },
|
||||
{ name: '售后状态', value: '售后中', field: '' }
|
||||
],
|
||||
shopList: [
|
||||
{ skuImg: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=137628589,3436980029&fm=26&gp=0.jpg',
|
||||
productName: 'DAD 气垫霜', skuNameStr: '粉色, 中瓶', skuId: '2525', sellPrice: '60', buyNum: '2', salePrice: '50' },
|
||||
{ skuImg: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=137628589,3436980029&fm=26&gp=0.jpg',
|
||||
productName: 'DAD 气垫霜', skuNameStr: '粉色, 中瓶', skuId: '2525', sellPrice: '60', buyNum: '2', salePrice: '50' }
|
||||
],
|
||||
recordList: [
|
||||
{ title: '申请平台介入', name: '刘十', time: '2020-05-08 15:30:56', type: '问题描述', value: '不退款', img: '举证图片',
|
||||
imgSrc: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=137628589,3436980029&fm=26&gp=0.jpg' },
|
||||
{ title: '拒绝退款', name: '王辉', time: '2020-04-08 17:30:20', type: '卖家留言', value: '不退款', img: '', imgSrc: '' },
|
||||
{ title: '发起了售后', name: '张强', time: '2020-03-25 13:25:45', type: '买家留言', value: '不要了, 买到的宝贝不符合预期', img: '', imgSrc: '' }
|
||||
],
|
||||
total: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.order_info_page {
|
||||
.order_info {
|
||||
overflow: hidden;
|
||||
p {
|
||||
width: 50%;
|
||||
float: left;
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
display: inline-block;
|
||||
&:nth-of-type(1) {
|
||||
width:130px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
color:#666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail_title {
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
position: relative;
|
||||
margin:50px 20px 20px;
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: -20px;
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #3A68F2;
|
||||
}
|
||||
}
|
||||
.goods_list {
|
||||
.good_details {
|
||||
border-bottom: 1px #E0E5EB solid;
|
||||
ul {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
padding: 30px 0;
|
||||
list-style: none;
|
||||
li {
|
||||
flex:3;
|
||||
display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
text-align: left;
|
||||
img {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius:4px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
&:nth-child(2),&:nth-child(3) {
|
||||
display: block;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
p {
|
||||
// text-align: center;
|
||||
&:nth-child(1) {
|
||||
font-weight: 600;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:nth-child(4) {
|
||||
font-weight: 600;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.total {
|
||||
padding-left: 20px;
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 30px 0;
|
||||
display: flex;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
// height: 40px;
|
||||
flex:3;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
&:nth-child(4) {
|
||||
// font-weight: 600;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
span {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
&:nth-of-type(1) {
|
||||
width: 40%;
|
||||
margin-right: 10%;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
width: 50%;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="store_info_page">
|
||||
<p v-for="(item,index) in storeInfo" :key="index">
|
||||
<span>{{ item.name }}:</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeInfo: [
|
||||
{ name: '店铺名称', value: '江山的店铺', field: '' },
|
||||
{ name: '合同有效期', value: '2020-06-30──2022-07-23', field: '' },
|
||||
{ name: '负责人', value: '江山', field: '' },
|
||||
{ name: '联系电话', value: '0755-56894556', field: '' },
|
||||
{ name: '联系地址', value: '广东省深圳市南山区科技园', field: '' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.store_info_page {
|
||||
padding: 20px 10%;
|
||||
overflow: hidden;
|
||||
p {
|
||||
width: 50%;
|
||||
float: left;
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
display: inline-block;
|
||||
&:nth-of-type(1) {
|
||||
width:130px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
color:#666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,462 @@
|
||||
<template>
|
||||
<div class="detail_page">
|
||||
<div class="content">
|
||||
<div class="head_box">
|
||||
售后详情
|
||||
<div class="btn_list">
|
||||
<el-button @click="refuse">拒绝售后</el-button>
|
||||
<el-button type="primary" @click="handle">同意售后</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="order_info">
|
||||
<p class="detail_title">订单信息</p>
|
||||
<ul class="order_list">
|
||||
<li v-for="(item,index) in orderInfo" :key="index">
|
||||
<p>{{ item.name }}:</p>
|
||||
<p :class="[{active: item.type ===1 || item.type ===2 || item.type ===4}]">
|
||||
<span @click="getInfo(item)">{{ item.value }}</span>
|
||||
<span v-if="item.type ===3" class="active" @click="getInfo(item)">
|
||||
查看物流
|
||||
</span>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="after_sale_shop">
|
||||
<p class="detail_title">售后商品</p>
|
||||
<div
|
||||
v-for="(item,index) in shopList"
|
||||
:key="index"
|
||||
class="goods_list"
|
||||
>
|
||||
<div class="good_details">
|
||||
<ul>
|
||||
<li>
|
||||
<img :src="item.skuImg" />
|
||||
</li>
|
||||
<li>
|
||||
<p>{{ item.productName }}</p>
|
||||
<p>{{ item.skuNameStr }}</p>
|
||||
<p>SKU: {{ item.skuId }}</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>¥{{ item.sellPrice*item.buyNum }}</p>
|
||||
<p>¥{{ `${item.sellPrice}*${item.buyNum}` }}</p>
|
||||
</li>
|
||||
<li> ¥{{ item.applyPrice * item.buyNum }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="total">
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li>退款总金额 </li>
|
||||
<li>¥{{ total }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="after_sales_record">
|
||||
<p class="detail_title">协商历史</p>
|
||||
<div v-for="(item,index) in recordList" :key="index" class="record_list">
|
||||
<div class="record_list_title">
|
||||
<p>{{ item.title }}</p>
|
||||
<p>{{ item.name }}</p>
|
||||
<p>{{ item.createTime }}</p>
|
||||
</div>
|
||||
<div class="record_list_content">
|
||||
<p>
|
||||
<span>{{ item.type }}:</span>
|
||||
<span>{{ item.actionNote }}</span>
|
||||
</p>
|
||||
<p v-if="item.img">
|
||||
<span>举证图片:</span>
|
||||
<img :src="item.imgSrc" alt="" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
:title="dialog.title"
|
||||
:visible.sync="dialog.visible"
|
||||
:fullscreen="!true"
|
||||
:before-close="close"
|
||||
width="55%"
|
||||
>
|
||||
<orderInfo v-if="dialog.type===1" />
|
||||
<storeInfo v-if="dialog.type===2" />
|
||||
<logistics v-if="dialog.type===3" />
|
||||
<buyer v-if="dialog.type===4" />
|
||||
<afterSale v-if="dialog.type===5" :dialog="dialog" @close="close" />
|
||||
<!-- <goods v-if="dialog.type===1" :info="info" />
|
||||
<audit-log v-if="dialog.type===2" :info="info" /> -->
|
||||
</Dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Dialog } from 'element-ui'
|
||||
import afterSale from './component/after-sales'
|
||||
import buyer from './component/buyer'
|
||||
import logistics from './component/logistics'
|
||||
import orderInfo from './component/order-info'
|
||||
import storeInfo from './component/store-info'
|
||||
import AfterSale from '@/api/AfterSale'
|
||||
export default {
|
||||
components: {
|
||||
Dialog,
|
||||
afterSale,
|
||||
buyer,
|
||||
logistics,
|
||||
orderInfo,
|
||||
storeInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
orderInfo: [
|
||||
{ name: '订单ID', value: '', type: 1, field: 'orderCode' },
|
||||
{ name: '售后订单ID', value: '', type: '', field: 'orderCode' },
|
||||
{ name: '支付时间', value: '', type: '', field: 'createTime' },
|
||||
{ name: '支付方式', value: '', type: '', field: 'payChannel' },
|
||||
{ name: '订单总金额', value: '', type: '', field: '' },
|
||||
{ name: '店铺名称', value: '', type: 2, field: 'memberAccount' },
|
||||
{ name: '物流单号', value: '', type: 3, field: 'logisticsNum' },
|
||||
{ name: '售后类型', value: '', type: '', field: 'returnType' },
|
||||
{ name: '买家账户', value: '', type: 4, field: 'recName' }
|
||||
],
|
||||
shopList: [
|
||||
{ skuImg: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=137628589,3436980029&fm=26&gp=0.jpg',
|
||||
productName: 'DAD 气垫霜', skuNameStr: '粉色, 中瓶', skuId: '2525', sellPrice: '60', buyNum: '2', salePrice: '50' },
|
||||
{ skuImg: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=137628589,3436980029&fm=26&gp=0.jpg',
|
||||
productName: 'DAD 气垫霜', skuNameStr: '粉色, 中瓶', skuId: '2525', sellPrice: '60', buyNum: '2', salePrice: '50' }
|
||||
],
|
||||
recordList: [
|
||||
{ title: '申请平台介入', name: '刘十', time: '2020-05-08 15:30:56', type: '问题描述', value: '不退款', img: '举证图片',
|
||||
imgSrc: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=137628589,3436980029&fm=26&gp=0.jpg' },
|
||||
{ title: '拒绝退款', name: '王辉', time: '2020-04-08 17:30:20', type: '卖家留言', value: '不退款', img: '', imgSrc: '' },
|
||||
{ title: '发起了售后', name: '张强', time: '2020-03-25 13:25:45', type: '买家留言', value: '不要了, 买到的宝贝不符合预期', img: '', imgSrc: '' }
|
||||
],
|
||||
total: 0,
|
||||
dialog: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
query() {
|
||||
return this.$route.query
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDetails()
|
||||
},
|
||||
methods: {
|
||||
async getDetails() {
|
||||
const res = await AfterSale.getInfo(this.query.id)
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
const o = resData.data
|
||||
this.getOrderInfo(o)
|
||||
this.shopList = o.orderProductDTOList
|
||||
this.getTotal(o.orderProductDTOList)
|
||||
this.recordList = o.moneyReturnActionHistoryList
|
||||
console.log(o, 'rr')
|
||||
}
|
||||
},
|
||||
getTotal(data) {
|
||||
if (data && data.length) {
|
||||
data.forEach(item => {
|
||||
this.total += item.applyPrice * item.buyNum
|
||||
})
|
||||
}
|
||||
},
|
||||
getOrderInfo(o) {
|
||||
const payChannel = {
|
||||
1: '微信支付',
|
||||
2: '支付宝支付',
|
||||
3: '余额支付'
|
||||
}
|
||||
const returnType = {
|
||||
1: '无售后',
|
||||
2: '退款',
|
||||
3: '退货'
|
||||
}
|
||||
this.orderInfo.map(item => {
|
||||
item.value = o[item.field] || ''
|
||||
if (item.field === 'payChannel') {
|
||||
item.value = payChannel[item.value]
|
||||
}
|
||||
if (item.field === 'returnType') {
|
||||
item.value = returnType[item.value]
|
||||
}
|
||||
})
|
||||
},
|
||||
handle() {
|
||||
this.dialog = {
|
||||
title: '同意售后',
|
||||
visible: true,
|
||||
type: 5,
|
||||
btnName: '同意售后',
|
||||
allow: true
|
||||
}
|
||||
},
|
||||
refuse() {
|
||||
this.dialog = {
|
||||
title: '拒绝售后',
|
||||
visible: true,
|
||||
type: 5,
|
||||
btnName: '拒绝售后'
|
||||
}
|
||||
},
|
||||
getInfo(item) {
|
||||
if (item.type === 1) {
|
||||
this.dialog = {
|
||||
title: '订单信息',
|
||||
visible: true,
|
||||
type: item.type
|
||||
}
|
||||
}
|
||||
|
||||
if (item.type === 2) {
|
||||
this.dialog = {
|
||||
title: '店铺信息',
|
||||
visible: true,
|
||||
type: item.type
|
||||
}
|
||||
}
|
||||
|
||||
if (item.type === 3) {
|
||||
this.dialog = {
|
||||
title: '物流信息',
|
||||
visible: true,
|
||||
type: item.type
|
||||
}
|
||||
}
|
||||
|
||||
if (item.type === 4) {
|
||||
this.dialog = {
|
||||
title: '买家信息',
|
||||
visible: true,
|
||||
type: item.type
|
||||
}
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialog = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.detail_page {
|
||||
margin-top: 10px;
|
||||
background-color: #fff;
|
||||
height: calc(100% - 10px);
|
||||
.content {
|
||||
padding: 20px;
|
||||
.head_box {
|
||||
overflow: hidden;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
font-size: 24px;
|
||||
border-bottom: 1px solid #E0E5EB;
|
||||
.btn_list {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.detail , .after_sales_record{
|
||||
min-height: 500px;
|
||||
background:rgba(255,255,255,1);
|
||||
box-shadow:0px 0px 10px 0px rgba(51,51,51,0.15);
|
||||
border-radius:4px;
|
||||
padding: 1px 10% 20px;
|
||||
margin-top: 15px;
|
||||
|
||||
.detail_title {
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
position: relative;
|
||||
margin:50px 20px 20px;
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: -20px;
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #3A68F2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order_info {
|
||||
.order_list {
|
||||
padding-left: 20px;
|
||||
overflow: hidden;
|
||||
list-style: none;
|
||||
li {
|
||||
float: left;
|
||||
width: calc(100% / 3);
|
||||
margin-bottom: 30px;
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
&:nth-child(1) {
|
||||
width: 20%;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.active {
|
||||
color: #3A68F2 !important;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.after_sale_shop {
|
||||
.goods_list {
|
||||
padding-left: 20px;
|
||||
.good_details {
|
||||
border-bottom: 1px #E0E5EB solid;
|
||||
ul {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
padding: 30px 0;
|
||||
li {
|
||||
flex:3;
|
||||
display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
text-align: left;
|
||||
img {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius:4px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
&:nth-child(2),&:nth-child(3) {
|
||||
display: block;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
p {
|
||||
// text-align: center;
|
||||
&:nth-child(1) {
|
||||
font-weight: 600;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:nth-child(4) {
|
||||
font-weight: 600;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.total {
|
||||
padding-left: 20px;
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 30px 0;
|
||||
display: flex;
|
||||
li {
|
||||
// height: 40px;
|
||||
flex:3;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
&:nth-child(4) {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.after_sales_record {
|
||||
p {
|
||||
margin: 0;
|
||||
padding:0 ;
|
||||
font-size: 16px;
|
||||
}
|
||||
.record_list {
|
||||
padding-left: 20px;
|
||||
.record_list_title {
|
||||
background: #F7F7F7;
|
||||
overflow: hidden;
|
||||
margin-bottom: 30px;
|
||||
p {
|
||||
float: left;
|
||||
text-indent: 10px;
|
||||
width: calc(100% / 3);
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
.record_list_content {
|
||||
p {
|
||||
overflow: hidden;
|
||||
margin-bottom: 30px;
|
||||
span {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 100px;
|
||||
&:nth-of-type(2) {
|
||||
text-indent: 10px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
color: #666666;
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-dialog__wrapper {
|
||||
.el-dialog__header {
|
||||
height: 70px;
|
||||
background-color: #3A68F2;
|
||||
.el-dialog__title {
|
||||
font-size:24px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<div class="after_sale_service_page">
|
||||
<div class="content">
|
||||
<el-tabs
|
||||
v-model="formParams.queryType"
|
||||
@tab-click="selectItem"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in tabList"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
/>
|
||||
</el-tabs>
|
||||
<div class="toolbar">
|
||||
<el-form
|
||||
:inline="true"
|
||||
:model="formParams"
|
||||
>
|
||||
<el-form-item label="店铺名称/编号">
|
||||
<el-input v-model="formParams.keyword" size="mini" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="订单id">
|
||||
<el-input v-model="formParams.orderCode" size="mini" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="下单时间">
|
||||
<el-date-picker
|
||||
v-model="date"
|
||||
size="mini"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="yyyy-MM-dd"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="query"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button
|
||||
plain
|
||||
size="mini"
|
||||
@click="reset"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="content_table">
|
||||
<div class="table">
|
||||
<el-table
|
||||
:data="tableData.returnInterventionDTOList"
|
||||
border
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="订单id"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="storeName"
|
||||
label="店铺名称"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tenantCode"
|
||||
label="店铺编码"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="returnProductCount"
|
||||
label="售后商品数量"
|
||||
/>
|
||||
<el-table-column
|
||||
v-if="formParams.queryType === '1'"
|
||||
prop="applySum"
|
||||
:formatter="getPrice"
|
||||
label="退款金额"
|
||||
/>
|
||||
<el-table-column
|
||||
v-else
|
||||
prop="value5"
|
||||
:formatter="getPrice"
|
||||
label="订单金额"
|
||||
/>
|
||||
<el-table-column label="操作">
|
||||
<template
|
||||
slot-scope="scope"
|
||||
>
|
||||
<el-button
|
||||
v-if="formParams.queryType ==='1'"
|
||||
type="text"
|
||||
size="small"
|
||||
@click.native.prevent="handle(scope.row.id)"
|
||||
>
|
||||
处理
|
||||
</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click.native.prevent="details(scope.row.id)"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="formParams.pageSize"
|
||||
:page.sync="formParams.pageIndex"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import AfterSale from '@/api/AfterSale'
|
||||
export default {
|
||||
components: {
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formParams: {
|
||||
keyword: '',
|
||||
orderCode: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
pageSize: 10,
|
||||
pageIndex: 1,
|
||||
queryType: '1'
|
||||
},
|
||||
date: [],
|
||||
tableData: {},
|
||||
tabList: [
|
||||
{ name: '待处理', id: '1' },
|
||||
{ name: '已处理', id: '2' }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
async getList() {
|
||||
const res = await AfterSale.getList(this.formParams)
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
this.tableData = resData.data
|
||||
}
|
||||
},
|
||||
getPrice(item, row, value) {
|
||||
return value / 100
|
||||
},
|
||||
query() {
|
||||
this.getList()
|
||||
},
|
||||
details(id) {
|
||||
this.$router.push({ path: '/after-sale-service/details', query: { id }})
|
||||
},
|
||||
handle(id) {
|
||||
this.$router.push({ path: '/after-sale-service/details', query: { id }})
|
||||
},
|
||||
reset() {
|
||||
this.formParams = {
|
||||
keyword: '',
|
||||
orderCode: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
pageSize: 10,
|
||||
pageIndex: 1,
|
||||
queryType: '1'
|
||||
}
|
||||
},
|
||||
fetch() {
|
||||
this.getList()
|
||||
},
|
||||
selectItem() {
|
||||
this.getList()
|
||||
},
|
||||
handleChange(value) {
|
||||
this.formParams.startTime = (value && value[0]) || ''
|
||||
this.formParams.endTime = (value && value[1]) || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
.after_sale_service_page {
|
||||
padding: 10px 20px;
|
||||
box-sizing: border-box;
|
||||
.content {
|
||||
background-color: #fff;
|
||||
.toolbar {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-table {
|
||||
th {
|
||||
background: #EEF3FF;
|
||||
color:#333333;
|
||||
font-size:16px;
|
||||
font-weight: 400;
|
||||
border-color: #E0E5EB;
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :title="title" :type="type"
|
||||
:visible.sync="isVisible"
|
||||
:width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="resource" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.resource.code')" prop="code">
|
||||
<el-input v-model="resource.code" :disabled="type==='edit'" @keyup.enter.native="submitForm" />
|
||||
<p class="note">建议使用:作为分隔符,并以view、add、update、delete、export、import、download、upload等关键词结尾</p>
|
||||
<p class="note">如:menu:add、 resource:view、 file:upload</p>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.resource.name')" prop="name" @keyup.enter.native="submitForm">
|
||||
<el-input v-model="resource.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.resource.describe')" prop="describe" @keyup.enter.native="submitForm">
|
||||
<el-input v-model="resource.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import resourceApi from '@/api/Resource.js'
|
||||
|
||||
export default {
|
||||
name: 'ResourceEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
resource: this.initResource(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
rules: {
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('rules.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 255,
|
||||
message: this.$t('rules.range4to10'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!this.resource.id) {
|
||||
// this.$get(`system/user/check/${value}`).then((r) => {
|
||||
// if (!r.data) {
|
||||
// callback(this.$t('rules.usernameExist'))
|
||||
// } else {
|
||||
// callback()
|
||||
// }
|
||||
// })
|
||||
} else {
|
||||
// callback()
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
name: {
|
||||
required: true,
|
||||
message: this.$t('rules.require'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return this.type === 'add'
|
||||
? this.$t('common.add')
|
||||
: this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initResource () {
|
||||
return {
|
||||
id: '',
|
||||
name: '',
|
||||
code: '',
|
||||
describe: ''
|
||||
}
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
setResource (val) {
|
||||
const that = this
|
||||
if (val) {
|
||||
that.resource = { ...val }
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.resource = this.initResource()
|
||||
},
|
||||
submitForm () {
|
||||
const that = this
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
that.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const that = this
|
||||
if (that.type === 'add') {
|
||||
that.save()
|
||||
} else {
|
||||
that.update()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const that = this
|
||||
resourceApi.save(this.resource).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
that.isVisible = false
|
||||
that.$message({
|
||||
message: that.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
that.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
resourceApi.update(this.resource).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
p.note {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1.4rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,477 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :title="$t('table.menu.icon')" :visible.sync="isVisible"
|
||||
:width="width"
|
||||
top="50px"
|
||||
>
|
||||
<el-input
|
||||
v-model="name" class="filter-item search-item" clearable
|
||||
placeholder="icon"
|
||||
@keyup.native="searchIcon"
|
||||
/>
|
||||
<el-tabs v-model="activeName" style="margin-top: -1rem;">
|
||||
<el-tab-pane :label="$t('common.tab.common')" name="first">
|
||||
<ul>
|
||||
<li v-for="icon in icons.commonIcons" :key="icon" class="icons-item">
|
||||
<span :class="{'active':activeIndex === icon}">
|
||||
<el-icon :class="icon" :title="icon" @click.native="chooseIcon(icon)" @dblclick.native="confirm" />
|
||||
</span>
|
||||
<p>{{ icon }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('common.tab.directivity')" name="second">
|
||||
<ul>
|
||||
<li v-for="icon in icons.directivityIcons" :key="icon">
|
||||
<span :class="{'active':activeIndex === icon}">
|
||||
<el-icon :class="icon" :title="icon" @click.native="chooseIcon(icon)" @dblclick.native="confirm" />
|
||||
</span>
|
||||
<p>{{ icon }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('common.tab.solid')" name="third">
|
||||
<ul>
|
||||
<li v-for="icon in icons.solidIcons" :key="icon">
|
||||
<span :class="{'active':activeIndex === icon}">
|
||||
<el-icon :class="icon" :title="icon" @click.native="chooseIcon(icon)" @dblclick.native="confirm" />
|
||||
</span>
|
||||
<p>{{ icon }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('common.tab.food')" name="fourth">
|
||||
<ul>
|
||||
<li v-for="icon in icons.foodIcons" :key="icon">
|
||||
<span :class="{'active':activeIndex === icon}">
|
||||
<el-icon :class="icon" :title="icon" @click.native="chooseIcon(icon)" @dblclick.native="confirm" />
|
||||
</span>
|
||||
<p>{{ icon }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="confirm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
const commonIcons = [
|
||||
'el-icon-eleme', 'el-icon-delete', 'el-icon-setting', 'el-icon-user', 'el-icon-phone-outline',
|
||||
'el-icon-more-outline', 'el-icon-star-off', 'el-icon-goods', 'el-icon-warning-outline', 'el-icon-zoom-in',
|
||||
'el-icon-zoom-out', 'el-icon-remove-outline', 'el-icon-circle-plus-outline', 'el-icon-circle-check', 'el-icon-circle-close',
|
||||
'el-icon-help', 'el-icon-minus', 'el-icon-plus', 'el-icon-check', 'el-icon-close', 'el-icon-picture-outline',
|
||||
'el-icon-picture-outline-round', 'el-icon-upload2', 'el-icon-download', 'el-icon-camera', 'el-icon-video-camera',
|
||||
'el-icon-bell', 'el-icon-video-pause', 'el-icon-video-play', 'el-icon-refresh', 'el-icon-refresh-right', 'el-icon-refresh-left',
|
||||
'el-icon-finished', 'el-icon-loading', 'el-icon-view', 'el-icon-c-scale-to-original', 'el-icon-date', 'el-icon-edit',
|
||||
'el-icon-edit-outline', 'el-icon-folder', 'el-icon-folder-opened', 'el-icon-folder-add', 'el-icon-folder-remove', 'el-icon-folder-delete',
|
||||
'el-icon-folder-checked', 'el-icon-tickets', 'el-icon-document-remove', 'el-icon-document-delete', 'el-icon-document-copy',
|
||||
'el-icon-document-checked', 'el-icon-document', 'el-icon-document-add', 'el-icon-printer', 'el-icon-paperclip',
|
||||
'el-icon-takeaway-box', 'el-icon-search', 'el-icon-monitor', 'el-icon-attract',
|
||||
'el-icon-mobile',
|
||||
'el-icon-scissors',
|
||||
'el-icon-umbrella',
|
||||
'el-icon-headset',
|
||||
'el-icon-brush',
|
||||
'el-icon-mouse',
|
||||
'el-icon-coordinate',
|
||||
'el-icon-magic-stick',
|
||||
'el-icon-reading',
|
||||
'el-icon-data-line',
|
||||
'el-icon-data-board',
|
||||
'el-icon-pie-chart',
|
||||
'el-icon-data-analysis',
|
||||
'el-icon-collection-tag',
|
||||
'el-icon-film',
|
||||
'el-icon-suitcase',
|
||||
'el-icon-suitcase-1',
|
||||
'el-icon-receiving',
|
||||
'el-icon-collection',
|
||||
'el-icon-files',
|
||||
'el-icon-notebook-1',
|
||||
'el-icon-notebook-2',
|
||||
'el-icon-toilet-paper',
|
||||
'el-icon-office-building',
|
||||
'el-icon-school',
|
||||
'el-icon-table-lamp',
|
||||
'el-icon-house',
|
||||
'el-icon-no-smoking',
|
||||
'el-icon-smoking',
|
||||
'el-icon-shopping-cart-full',
|
||||
'el-icon-shopping-cart-1',
|
||||
'el-icon-shopping-cart-2',
|
||||
'el-icon-shopping-bag-1',
|
||||
'el-icon-shopping-bag-2',
|
||||
'el-icon-sold-out',
|
||||
'el-icon-sell',
|
||||
'el-icon-present',
|
||||
'el-icon-box',
|
||||
'el-icon-bank-card',
|
||||
'el-icon-money',
|
||||
'el-icon-coin',
|
||||
'el-icon-wallet',
|
||||
'el-icon-discount',
|
||||
'el-icon-price-tag',
|
||||
'el-icon-news',
|
||||
'el-icon-guide',
|
||||
'el-icon-male',
|
||||
'el-icon-female',
|
||||
'el-icon-thumb',
|
||||
'el-icon-cpu',
|
||||
'el-icon-link',
|
||||
'el-icon-connection',
|
||||
'el-icon-open',
|
||||
'el-icon-turn-off',
|
||||
'el-icon-set-up',
|
||||
'el-icon-chat-round',
|
||||
'el-icon-chat-line-round',
|
||||
'el-icon-chat-square',
|
||||
'el-icon-chat-dot-round',
|
||||
'el-icon-chat-dot-square',
|
||||
'el-icon-chat-line-square',
|
||||
'el-icon-message',
|
||||
'el-icon-postcard',
|
||||
'el-icon-position',
|
||||
'el-icon-turn-off-microphone',
|
||||
'el-icon-microphone',
|
||||
'el-icon-close-notification',
|
||||
'el-icon-bangzhu',
|
||||
'el-icon-time',
|
||||
'el-icon-odometer',
|
||||
'el-icon-crop',
|
||||
'el-icon-aim',
|
||||
'el-icon-switch-button',
|
||||
'el-icon-full-screen',
|
||||
'el-icon-copy-document',
|
||||
'el-icon-mic',
|
||||
'el-icon-stopwatch',
|
||||
'el-icon-medal-1',
|
||||
'el-icon-medal',
|
||||
'el-icon-trophy',
|
||||
'el-icon-trophy-1',
|
||||
'el-icon-first-aid-kit',
|
||||
'el-icon-discover',
|
||||
'el-icon-place',
|
||||
'el-icon-location-outline',
|
||||
'el-icon-location-information',
|
||||
'el-icon-add-location',
|
||||
'el-icon-delete-location',
|
||||
'el-icon-map-location',
|
||||
'el-icon-alarm-clock',
|
||||
'el-icon-timer',
|
||||
'el-icon-watch-1',
|
||||
'el-icon-watch',
|
||||
'el-icon-lock',
|
||||
'el-icon-unlock',
|
||||
'el-icon-key',
|
||||
'el-icon-service',
|
||||
'el-icon-mobile-phone',
|
||||
'el-icon-bicycle',
|
||||
'el-icon-truck',
|
||||
'el-icon-ship',
|
||||
'el-icon-basketball',
|
||||
'el-icon-football',
|
||||
'el-icon-soccer',
|
||||
'el-icon-baseball'
|
||||
]
|
||||
const directivityIcons = [
|
||||
'el-icon-d-caret',
|
||||
'el-icon-caret-left',
|
||||
'el-icon-caret-right',
|
||||
'el-icon-caret-bottom',
|
||||
'el-icon-caret-top',
|
||||
'el-icon-bottom-left',
|
||||
'el-icon-bottom-right',
|
||||
'el-icon-back',
|
||||
'el-icon-right',
|
||||
'el-icon-bottom',
|
||||
'el-icon-top',
|
||||
'el-icon-top-left',
|
||||
'el-icon-top-right',
|
||||
'el-icon-arrow-left',
|
||||
'el-icon-arrow-right',
|
||||
'el-icon-arrow-down',
|
||||
'el-icon-arrow-up',
|
||||
'el-icon-d-arrow-left',
|
||||
'el-icon-d-arrow-right',
|
||||
'el-icon-sort',
|
||||
'el-icon-sort-up',
|
||||
'el-icon-sort-down',
|
||||
'el-icon-rank'
|
||||
]
|
||||
const solidIcons = [
|
||||
'el-icon-question',
|
||||
'el-icon-info',
|
||||
'el-icon-remove',
|
||||
'el-icon-circle-plus',
|
||||
'el-icon-success',
|
||||
'el-icon-error',
|
||||
'el-icon-platform-eleme',
|
||||
'el-icon-delete-solid',
|
||||
'el-icon-s-tools',
|
||||
'el-icon-user-solid',
|
||||
'el-icon-phone',
|
||||
'el-icon-star-on',
|
||||
'el-icon-s-goods',
|
||||
'el-icon-warning',
|
||||
'el-icon-s-help',
|
||||
'el-icon-picture',
|
||||
'el-icon-upload',
|
||||
'el-icon-camera-solid',
|
||||
'el-icon-video-camera-solid',
|
||||
'el-icon-message-solid',
|
||||
'el-icon-s-cooperation',
|
||||
'el-icon-s-order',
|
||||
'el-icon-s-platform',
|
||||
'el-icon-s-fold',
|
||||
'el-icon-s-unfold',
|
||||
'el-icon-s-operation',
|
||||
'el-icon-s-promotion',
|
||||
'el-icon-s-home',
|
||||
'el-icon-s-release',
|
||||
'el-icon-s-ticket',
|
||||
'el-icon-s-management',
|
||||
'el-icon-s-open',
|
||||
'el-icon-s-shop',
|
||||
'el-icon-s-marketing',
|
||||
'el-icon-s-flag',
|
||||
'el-icon-s-comment',
|
||||
'el-icon-s-finance',
|
||||
'el-icon-s-claim',
|
||||
'el-icon-s-custom',
|
||||
'el-icon-s-opportunity',
|
||||
'el-icon-s-data',
|
||||
'el-icon-s-check',
|
||||
'el-icon-s-grid',
|
||||
'el-icon-menu',
|
||||
'el-icon-share',
|
||||
'el-icon-d-caret',
|
||||
'el-icon-caret-left',
|
||||
'el-icon-caret-right',
|
||||
'el-icon-caret-bottom',
|
||||
'el-icon-caret-top',
|
||||
'el-icon-location'
|
||||
]
|
||||
const foodIcons = [
|
||||
'el-icon-dish',
|
||||
'el-icon-dish-1',
|
||||
'el-icon-food',
|
||||
'el-icon-chicken',
|
||||
'el-icon-fork-spoon',
|
||||
'el-icon-knife-fork',
|
||||
'el-icon-burger',
|
||||
'el-icon-tableware',
|
||||
'el-icon-sugar',
|
||||
'el-icon-dessert',
|
||||
'el-icon-ice-cream',
|
||||
'el-icon-hot-water',
|
||||
'el-icon-water-cup',
|
||||
'el-icon-coffee-cup',
|
||||
'el-icon-cold-drink',
|
||||
'el-icon-goblet',
|
||||
'el-icon-goblet-full',
|
||||
'el-icon-goblet-square',
|
||||
'el-icon-goblet-square-full',
|
||||
'el-icon-refrigerator',
|
||||
'el-icon-grape',
|
||||
'el-icon-watermelon',
|
||||
'el-icon-cherry',
|
||||
'el-icon-apple',
|
||||
'el-icon-pear',
|
||||
'el-icon-orange',
|
||||
'el-icon-coffee',
|
||||
'el-icon-ice-tea',
|
||||
'el-icon-ice-drink',
|
||||
'el-icon-milk-tea',
|
||||
'el-icon-potato-strips',
|
||||
'el-icon-lollipop',
|
||||
'el-icon-ice-cream-square',
|
||||
'el-icon-ice-cream-round'
|
||||
]
|
||||
export default {
|
||||
name: 'Icons',
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
name: '',
|
||||
icons: {
|
||||
commonIcons,
|
||||
directivityIcons,
|
||||
solidIcons,
|
||||
foodIcons
|
||||
},
|
||||
activeIndex: '',
|
||||
choosedIcon: '',
|
||||
activeName: 'first',
|
||||
screenWidth: 0,
|
||||
width: this.initWidth()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '60%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
this.activeName = 'first'
|
||||
this.choosedIcon = this.activeIndex = ''
|
||||
},
|
||||
chooseIcon (icon) {
|
||||
this.activeIndex = icon
|
||||
this.choosedIcon = icon
|
||||
},
|
||||
confirm () {
|
||||
if (!this.choosedIcon) {
|
||||
this.$message({
|
||||
message: this.$t('tips.chooseNothing'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$emit('choose', this.choosedIcon)
|
||||
this.activeName = 'first'
|
||||
this.choosedIcon = this.activeIndex = ''
|
||||
},
|
||||
searchIcon () {
|
||||
if (this.name.trim() === '') {
|
||||
this.icons.commonIcons = commonIcons
|
||||
this.icons.directivityIcons = directivityIcons
|
||||
this.icons.solidIcons = solidIcons
|
||||
this.icons.foodIcons = foodIcons
|
||||
this.activeName = 'first'
|
||||
}
|
||||
const commonList = commonIcons.filter(item => item.indexOf(this.name) !== -1)
|
||||
const directivityList = directivityIcons.filter(item => item.indexOf(this.name) !== -1)
|
||||
const solidList = solidIcons.filter(item => item.indexOf(this.name) !== -1)
|
||||
const foodIconsList = foodIcons.filter(item => item.indexOf(this.name) !== -1)
|
||||
|
||||
this.icons.commonIcons = commonList
|
||||
this.icons.directivityIcons = directivityList
|
||||
this.icons.solidIcons = solidList
|
||||
this.icons.foodIcons = foodIconsList
|
||||
|
||||
if (commonList.length > 0) {
|
||||
this.activeName = 'first'
|
||||
return
|
||||
}
|
||||
|
||||
if (directivityList.length > 0) {
|
||||
this.activeName = 'second'
|
||||
return
|
||||
}
|
||||
|
||||
if (solidList.length > 0) {
|
||||
this.activeName = 'third'
|
||||
return
|
||||
}
|
||||
|
||||
if (foodIconsList.length > 0) {
|
||||
this.activeName = 'fourth'
|
||||
return
|
||||
}
|
||||
|
||||
this.activeName = 'first'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.search-item {
|
||||
margin: 0px 0 10px;
|
||||
}
|
||||
ul {
|
||||
// overflow-y: auto;
|
||||
// padding-left: 0rem;
|
||||
// margin-top: 0rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
zoom: 1;
|
||||
height: 500px;
|
||||
li {
|
||||
// list-style: none;
|
||||
// float: left;
|
||||
// width: 60px;
|
||||
// text-align: center;
|
||||
// cursor: pointer;
|
||||
// color: #555;
|
||||
// transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
||||
// position: relative;
|
||||
// // margin: 3px 0;
|
||||
// border-radius: 4px;
|
||||
// background-color: #fff;
|
||||
// overflow: hidden;
|
||||
padding: 0;
|
||||
float: left;
|
||||
margin: 2px;
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
color: #5c6b77;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
span.active {
|
||||
i {
|
||||
border-radius: 2px;
|
||||
border-color: #4a4a48;
|
||||
background-color: #4a4a48;
|
||||
color: #fff;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
i {
|
||||
font-size: 1.7rem;
|
||||
border: 1px solid #f1f1f1;
|
||||
padding: 0.2rem;
|
||||
margin: 0.3rem;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
border-radius: 2px;
|
||||
border-color: #4a4a48;
|
||||
background-color: #4a4a48;
|
||||
color: #fff;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
li p {
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
margin: 2px 0;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,628 @@
|
||||
<template>
|
||||
<div class="menu">
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="6" :xs="24">
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="label" :placeholder="$t('table.menu.label')" class="filter-item search-item"
|
||||
clearable @keyup.enter.native="search"
|
||||
/>
|
||||
<el-tooltip class="item" content="新增/删除时,请先勾选菜单" effect="dark" placement="right">
|
||||
<el-dropdown
|
||||
v-has-any-permission="['menu:add','menu:delete','menu:export']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['menu:add']" @click.native="add">
|
||||
{{ $t('table.add') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['menu:delete']" @click.native="deleteMenu">
|
||||
{{ $t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<commonTree ref="menuTree" :tree-data="menuTree" @nodeClick="nodeClick">
|
||||
<template scope="treeNode">
|
||||
<span class="tree-icon">
|
||||
<i :class="treeNode.data.icon ? treeNode.data.icon : 'el-icon-document'"></i>
|
||||
</span>
|
||||
<span class="tree-icon">
|
||||
<el-badge :type="treeNode.data.isEnable ? 'success' :'danger'" class="status-item" is-dot />
|
||||
</span>
|
||||
</template>
|
||||
</commonTree>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="8" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ menu.id === '' ? this.$t('common.add') : this.$t('common.edit') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-form
|
||||
ref="form" :model="menu" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.menu.parentId')" prop="parentId">
|
||||
<el-tooltip :content="$t('tips.topId')" class="item" effect="dark" placement="right">
|
||||
<el-input v-model="menu.parentId" readonly />
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.menu.label')" prop="label">
|
||||
<el-input v-model="menu.label" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label='$t("table.menu.type")' prop='type'>
|
||||
<el-radio-group v-model='menu.type'>
|
||||
<el-radio label='DIR'>目录</el-radio>
|
||||
<el-radio label='MENU'>菜单</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>-->
|
||||
<el-form-item :label="$t('table.menu.path')" prop="path">
|
||||
<el-input v-model="menu.path" @keyup.native="menuPath" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.menu.component')" prop="component">
|
||||
<el-input v-model="menu.component" />
|
||||
<span>{{ menuComponent }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.menu.icon')" prop="icon">
|
||||
<el-input v-model="menu.icon">
|
||||
<el-button slot="append" icon="el-icon-brush" style="padding-left: 0;" @click="chooseIcons" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="$t('table.status')" prop="isEnable">
|
||||
<el-switch
|
||||
v-model="menu.isEnable" :active-text="$t('common.status.valid')"
|
||||
:inactive-text="$t('common.status.invalid')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="$t('table.menu.isPublic')" prop="isPublic">
|
||||
<el-switch
|
||||
v-model="menu.isPublic" :active-text="$t('common.yes')"
|
||||
:inactive-text="$t('common.no')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('table.menu.sortValue')" prop="sortValue">
|
||||
<el-input-number v-model="menu.sortValue" :max="100" :min="0" @change="handleNumChange" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.menu.group')" prop="group">
|
||||
<el-tooltip class="item" content="用于区分多组菜单" effect="dark" placement="right">
|
||||
<el-input v-model="menu.group" />
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.menu.describe')" prop="describe">
|
||||
<el-input v-model="menu.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top: -2rem;">
|
||||
<el-row>
|
||||
<el-col :span="24" style="text-align: right">
|
||||
<el-button plain type="primary" @click="submit">{{ menu.id === '' ? this.$t('common.add') :
|
||||
this.$t('common.edit') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :sm="10" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="resourceQueryParams.model.code" :placeholder="$t('table.resource.code')" class="filter-item search-item"
|
||||
clearable
|
||||
/>
|
||||
<el-input
|
||||
v-model="resourceQueryParams.model.name" :placeholder="$t('table.resource.name')" class="filter-item search-item"
|
||||
clearable
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="resourceSearch">{{ $t('table.search') }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['resource:add','resource:delete']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-has-permission="['resource:add']" :disabled="!menu.id"
|
||||
@click.native="resourceAdd"
|
||||
>{{ $t('table.add') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['resource:delete']" @click.native="resourceBatchDelete">{{
|
||||
$t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="resourceTableKey"
|
||||
ref="resourceTable"
|
||||
v-loading="resourceLoading"
|
||||
:data="resourceTableData.records"
|
||||
border
|
||||
fit
|
||||
style="width: 100%;"
|
||||
@selection-change="onResourceSelectChange"
|
||||
@sort-change="resourceSortChange"
|
||||
@filter-change="resourceFilterChange"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" />
|
||||
<el-table-column
|
||||
:label="$t('table.resource.code')" :show-overflow-tooltip="true" align="center"
|
||||
prop="code"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.resource.name')" :show-overflow-tooltip="true" align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" align="center" class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-hasPermission="['resource:update']" class="el-icon-edit table-operation" style="color: #2db7f5;"
|
||||
@click="resourceEdit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['resource:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="resourceSingleDelete(row)"
|
||||
></i>
|
||||
<el-link v-has-no-permission="['resource:update','resource:delete']" class="no-perm">{{
|
||||
$t('tips.noPermission') }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="resourceTableData.total>0"
|
||||
:limit.sync="resourceQueryParams.size"
|
||||
:page.sync="resourceQueryParams.current"
|
||||
:total="Number(resourceTableData.total)"
|
||||
@pagination="resourceFetch"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<Icons :dialog-visible="iconVisible" @choose="chooseIcon" @close="iconVisible = false" />
|
||||
<resource-edit
|
||||
ref="resourceEdit" :dialog-visible="dialog.isVisible" :type="dialog.type"
|
||||
@close="resourceEditClose" @success="resourceEditSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import commonTree from '@/components/ceres/CommonTree.vue'
|
||||
import Icons from './Icons'
|
||||
import ResourceEdit from './Edit'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import menuApi from '@/api/Menu.js'
|
||||
import resourceApi from '@/api/Resource.js'
|
||||
import { initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'MenuManage',
|
||||
directives: { elDragDialog },
|
||||
components: { Icons, commonTree, Pagination, ResourceEdit },
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
iconVisible: false,
|
||||
menuTree: [],
|
||||
label: '',
|
||||
menu: this.initMenu(),
|
||||
resourceQueryParams: initQueryParams({
|
||||
model: {
|
||||
menuId: null
|
||||
}
|
||||
}),
|
||||
resourceTableKey: 0,
|
||||
resourceLoading: false,
|
||||
resourceSelection: [],
|
||||
resourceTableData: {
|
||||
total: 0
|
||||
},
|
||||
rules: {
|
||||
label: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range2to10'), trigger: 'blur' }
|
||||
],
|
||||
path: [{ max: 255, message: this.$t('rules.noMoreThan100'), trigger: 'blur' },
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const isUrl = this.isUrl(this.menu.path)
|
||||
|
||||
if (value === '/' || (!isUrl && value.endsWith('/'))) {
|
||||
callback('请填写有效的路由地址')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'blur'
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
menuComponent() {
|
||||
let comp = ''
|
||||
if (this.menu.path && this.menu.path !== '/') {
|
||||
const isUrl = this.isUrl(this.menu.path)
|
||||
if (isUrl) {
|
||||
comp = `跳转地址:${this.menu.path}`
|
||||
} else {
|
||||
// comp = `前端组件:src/views/ceres${this.menu.path}/Index.vue`
|
||||
comp = `组件路径:src/views/${this.menu.component}.vue`
|
||||
}
|
||||
} else {
|
||||
comp = `组件路径:src/views/ceres/Index.vue`
|
||||
}
|
||||
return comp
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'menu.path': function () {
|
||||
this.computedComponent()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initMenuTree()
|
||||
},
|
||||
methods: {
|
||||
isUrl(path) {
|
||||
const urls = ['http://', '/http://', 'https://', '/https://', 'www.', '/www.']
|
||||
const urlIndex = urls.findIndex(item => {
|
||||
return path.startsWith(item)
|
||||
})
|
||||
return urlIndex >= 0
|
||||
},
|
||||
menuPath() {
|
||||
const isUrl = this.isUrl(this.menu.path)
|
||||
if (!isUrl && !this.menu.path.startsWith('/')) {
|
||||
this.menu.path = '/' + this.menu.path
|
||||
} else if (isUrl) {
|
||||
if (this.menu.path.startsWith('/')) {
|
||||
this.menu.path = this.menu.path.substr(1)
|
||||
}
|
||||
}
|
||||
},
|
||||
computedComponent() {
|
||||
const isUrl = this.isUrl(this.menu.path)
|
||||
if (isUrl) {
|
||||
this.menu.component = 'Layout'
|
||||
} else {
|
||||
if (this.menu.path) {
|
||||
this.menu.component = `ceres${this.menu.path}/Index`
|
||||
} else {
|
||||
this.menu.component = `ceres/Index`
|
||||
}
|
||||
}
|
||||
},
|
||||
initMenuTree() {
|
||||
menuApi.allTree().then((response) => {
|
||||
const res = response.data
|
||||
this.menuTree = res.data
|
||||
})
|
||||
},
|
||||
initMenu() {
|
||||
return {
|
||||
id: '',
|
||||
label: '',
|
||||
describe: '',
|
||||
code: '',
|
||||
isPublic: false,
|
||||
path: '',
|
||||
component: '',
|
||||
isEnable: true,
|
||||
sortValue: '',
|
||||
parentId: 0,
|
||||
icon: '',
|
||||
group: ''
|
||||
}
|
||||
},
|
||||
nodeClick(data) {
|
||||
this.menu = { ...data }
|
||||
this.$refs.form.clearValidate()
|
||||
|
||||
this.resourceQueryParams.model.menuId = data.id
|
||||
this.resourceSearch()
|
||||
},
|
||||
handleNumChange(val) {
|
||||
this.menu.sortValue = val
|
||||
},
|
||||
chooseIcons() {
|
||||
this.iconVisible = true
|
||||
},
|
||||
chooseIcon(icon) {
|
||||
this.menu.icon = icon
|
||||
this.iconVisible = false
|
||||
},
|
||||
submit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.menu.createTime = this.menu.updateTime = null
|
||||
if (this.menu.id) {
|
||||
this.update()
|
||||
} else {
|
||||
this.save()
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
save() {
|
||||
console.log(this.menu.component)
|
||||
menuApi.save(this.menu)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
update() {
|
||||
console.log(this.menu)
|
||||
menuApi.update(this.menu)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.initMenuTree()
|
||||
this.label = ''
|
||||
this.resetForm()
|
||||
},
|
||||
search() {
|
||||
this.$refs.menuTree.$refs.treeRef.filter(this.label)
|
||||
},
|
||||
add() {
|
||||
this.resetForm()
|
||||
const checked = this.$refs.menuTree.$refs.treeRef.getCheckedKeys()
|
||||
if (checked.length > 1) {
|
||||
this.$message({
|
||||
message: this.$t('tips.onlyChooseOne'),
|
||||
type: 'warning'
|
||||
})
|
||||
} else if (checked.length > 0) {
|
||||
this.menu.parentId = checked[0]
|
||||
} else {
|
||||
this.menu.parentId = 0
|
||||
}
|
||||
this.resourceQueryParams.model.menuId = null
|
||||
this.resourceReset()
|
||||
},
|
||||
deleteMenu() {
|
||||
const checked = this.$refs.menuTree.$refs.treeRef.getCheckedKeys()
|
||||
if (checked.length === 0) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noNodeSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
} else {
|
||||
this.$confirm(this.$t('tips.confirmDeleteNode'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
menuApi.delete({ ids: checked })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
this.resourceQueryParams.model.menuId = null
|
||||
this.resourceReset()
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$refs.menuTree.$refs.treeRef.setCheckedKeys([])
|
||||
})
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.menu = this.initMenu()
|
||||
},
|
||||
resourceAdd() {
|
||||
this.dialog.type = 'add'
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.resourceEdit.setResource({
|
||||
menuId: this.menu.id
|
||||
})
|
||||
},
|
||||
resourceEdit(row) {
|
||||
this.dialog.type = 'edit'
|
||||
this.dialog.isVisible = true
|
||||
row.menuId = this.menu.id
|
||||
this.$refs.resourceEdit.setResource(row)
|
||||
},
|
||||
resourceSingleDelete(row) {
|
||||
this.$refs.resourceTable.clearSelection()
|
||||
this.$refs.resourceTable.toggleRowSelection(row, true)
|
||||
this.resourceBatchDelete()
|
||||
},
|
||||
resourceBatchDelete() {
|
||||
if (!this.resourceSelection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t('tips.confirmDeleteNode'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = this.resourceSelection.map((item) => item.id)
|
||||
resourceApi.delete({ ids: ids }).then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.resourceReset()
|
||||
})
|
||||
})
|
||||
},
|
||||
resourceReset() {
|
||||
this.resourceQueryParams = initQueryParams({
|
||||
model: {
|
||||
menuId: this.resourceQueryParams.menuId
|
||||
}
|
||||
})
|
||||
this.$refs.resourceTable.clearSort()
|
||||
this.$refs.resourceTable.clearFilter()
|
||||
this.resourceSearch()
|
||||
},
|
||||
resourceSearch() {
|
||||
this.resourceFetch({
|
||||
...this.resourceQueryParams
|
||||
})
|
||||
},
|
||||
resourceFetch(params = {}) {
|
||||
if (this.resourceQueryParams.timeRange) {
|
||||
this.resourceQueryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.resourceQueryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.resourceQueryParams.current = params.current ? params.current : this.resourceQueryParams.current
|
||||
this.resourceQueryParams.size = params.size ? params.size : this.resourceQueryParams.size
|
||||
|
||||
if (this.resourceQueryParams.model.menuId) {
|
||||
this.resourceLoading = true
|
||||
resourceApi.page(this.resourceQueryParams)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.resourceTableData = res.data
|
||||
}
|
||||
})
|
||||
.finally(() => this.resourceLoading = false)
|
||||
} else {
|
||||
this.resourceTableData = {}
|
||||
}
|
||||
},
|
||||
resourceSortChange(val) {
|
||||
this.resourceQueryParams.sort = val.prop
|
||||
this.resourceQueryParams.order = val.order
|
||||
if (this.resourceQueryParams.sort) {
|
||||
this.resourceSearch()
|
||||
}
|
||||
},
|
||||
resourceFilterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.resourceQueryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.resourceQueryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.resourceSearch()
|
||||
},
|
||||
onResourceSelectChange(selection) {
|
||||
this.resourceSelection = selection
|
||||
},
|
||||
resourceEditClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
resourceEditSuccess() {
|
||||
this.resourceSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.menu {
|
||||
margin: 10px;
|
||||
|
||||
.app-container {
|
||||
margin: 0 0 10px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
|
||||
.el-card__header {
|
||||
padding: 10px 20px !important;
|
||||
border-bottom: 1px solid #f1f1f1 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :title="title" :type="type"
|
||||
:visible.sync="isVisible" :width="width"
|
||||
top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="role" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.role.code')" prop="code">
|
||||
<el-input v-model="role.code" :disabled="type==='edit'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.role.name')" prop="name">
|
||||
<el-input v-model="role.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.role.status')" prop="status">
|
||||
<el-radio-group v-model="role.status">
|
||||
<el-radio-button :label="true">{{ $t('common.status.valid') }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t('common.status.invalid') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.role.describe')" prop="describe">
|
||||
<el-input v-model="role.describe" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.role.dsType')" prop="dsType">
|
||||
<el-radio-group v-model="role.dsType.code" @change="dsTypeChange">
|
||||
<el-radio-button v-for="(item, key, index) in enums.DataScopeType" :key="index" :label="key" :value="key">
|
||||
{{ item }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :hidden="orgHidden" :label="$t('table.role.orgList')" prop="orgList">
|
||||
<el-tree
|
||||
ref="orgTree"
|
||||
:check-strictly="true"
|
||||
:data="orgList"
|
||||
:default-checked-keys="role.orgList"
|
||||
:default-expanded-keys="role.orgList"
|
||||
:expand-on-click-node="false"
|
||||
highlight-current
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roleApi from '@/api/Role.js'
|
||||
import orgApi from '@/api/Org.js'
|
||||
|
||||
export default {
|
||||
name: 'RoleEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
role: this.initRole(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
orgList: [],
|
||||
orgHidden: true,
|
||||
enums: {
|
||||
DataScopeType: {}
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range4to10'), trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!this.type === 'add' && value.trim().length > 0) {
|
||||
roleApi.check(value)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.data) {
|
||||
callback('编码重复')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
callback()
|
||||
}, trigger: 'blur'
|
||||
}
|
||||
],
|
||||
status: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
orgList: {
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.role.dsType.code === 'CUSTOMIZE') {
|
||||
if (this.$refs.orgTree.getCheckedKeys().length > 0) {
|
||||
callback()
|
||||
} else {
|
||||
callback('请至少选择一个单位或部门')
|
||||
}
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return this.type === 'add' ? this.$t('common.add') : this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted() {
|
||||
this.initOrg()
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initRole() {
|
||||
return {
|
||||
id: '',
|
||||
code: '',
|
||||
name: '',
|
||||
orgList: [],
|
||||
status: true,
|
||||
describe: '',
|
||||
dsType: {
|
||||
code: 'SELF',
|
||||
desc: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
initOrg() {
|
||||
orgApi.allTree({ status: true })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
|
||||
this.orgList = res.data
|
||||
})
|
||||
},
|
||||
loadListOptions({ callback }) {
|
||||
callback()
|
||||
},
|
||||
setRole(val = {}) {
|
||||
const vm = this
|
||||
|
||||
if (val['enums']) {
|
||||
vm.enums = val['enums']
|
||||
}
|
||||
|
||||
if (val['row']) {
|
||||
vm.role = { ...val['row'] }
|
||||
|
||||
this.orgHidden = vm.role.dsType.code !== 'CUSTOMIZE'
|
||||
if (!this.orgHidden) {
|
||||
roleApi.getDetails(vm.role.id)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.role.orgList = res.data.orgList
|
||||
this.$refs.orgTree.setCheckedKeys(res.data.orgList)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.role = this.initRole()
|
||||
this.orgHidden = true
|
||||
this.$refs.orgTree.setCheckedKeys([])
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
if (this.orgHidden && this.role.orgList) {
|
||||
this.role.orgList.length = 0
|
||||
} else {
|
||||
this.role.orgList = this.$refs.orgTree.getCheckedKeys()
|
||||
}
|
||||
|
||||
if (vm.type === 'add') {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save() {
|
||||
const vm = this
|
||||
roleApi.save(this.role)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update() {
|
||||
roleApi.update(this.role)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
dsTypeChange(value) {
|
||||
this.orgHidden = value !== 'CUSTOMIZE'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,530 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="queryParams.model.code" :placeholder="$t('table.role.code')" class="filter-item search-item" />
|
||||
<el-input v-model="queryParams.model.name" :placeholder="$t('table.role.name')" class="filter-item search-item" />
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">
|
||||
{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-has-permission="['user:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="[ 'role:delete', 'role:export', 'role:import']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['role:delete']" @click.native="batchDelete">
|
||||
{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['role:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['role:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['role:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.role.code')"
|
||||
align="center"
|
||||
prop="code"
|
||||
width="200px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.role.name')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.role.describe')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="describe"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="dsTypeList"
|
||||
column-key="dsType.code"
|
||||
:label="$t('table.role.dsType')"
|
||||
align="center"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.dsType ? scope.row.dsType.desc : '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
column-key="readonly"
|
||||
:filters="[
|
||||
{ text: $t('common.yes'), value: true },
|
||||
{ text: $t('common.no'), value: false }
|
||||
]"
|
||||
:label="$t('table.role.readonly')"
|
||||
align="center"
|
||||
width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.readonly ? $t('common.yes') : $t('common.no') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
column-key="status"
|
||||
:filters="[
|
||||
{ text: $t('common.status.valid'), value: true },
|
||||
{ text: $t('common.status.invalid'), value: false }
|
||||
]"
|
||||
:label="$t('table.role.status')"
|
||||
class-name="status-col"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag :type="row.status | statusFilter">{{
|
||||
row.status ? $t("common.status.valid") : $t("common.status.invalid")
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')"
|
||||
align="center"
|
||||
column-key="operation"
|
||||
class-name="small-padding fixed-width"
|
||||
width="140px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-hasPermission="['role:update']"
|
||||
class="el-icon-edit table-operation"
|
||||
style="color: #2db7f5;"
|
||||
title="修改"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['role:delete']"
|
||||
class="el-icon-delete table-operation"
|
||||
style="color: #f50;"
|
||||
title="删除"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['role:auth']"
|
||||
class="el-icon-user table-operation"
|
||||
style="color: #87d068;"
|
||||
title="授权用户"
|
||||
@click="authUser(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['role:config']"
|
||||
class="el-icon-setting table-operation"
|
||||
style="color: #E6A23C"
|
||||
title="分配权限"
|
||||
@click="authResource(row)"
|
||||
></i>
|
||||
|
||||
<!-- dropdown 有时候会有bug,不知道这么解决 -->
|
||||
|
||||
<!-- <el-dropdown v-has-any-permission="['role:delete','role:auth','role:config']">
|
||||
<span class="el-dropdown-link">
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="singleDelete(row)" icon="el-icon-delete" v-hasPermission="['role:delete']">删除</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="authUser(row)" icon="el-icon-user" v-hasPermission="['role:auth']">授权</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="authResource(row)" icon="el-icon-setting" v-hasPermission="['role:config']">配置</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown> -->
|
||||
|
||||
<el-link
|
||||
v-has-no-permission="[
|
||||
'role:update',
|
||||
'role:delete',
|
||||
'role:auth',
|
||||
'role:config'
|
||||
]"
|
||||
class="no-perm"
|
||||
>{{ $t("tips.noPermission") }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<role-edit
|
||||
ref="edit"
|
||||
:dialog-visible="dialog.isVisible"
|
||||
:type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<user-role
|
||||
ref="userRole"
|
||||
:dialog-visible="userRoleDialog.isVisible"
|
||||
@close="userRoleClose"
|
||||
@success="userRoleSuccess"
|
||||
/>
|
||||
<role-authority
|
||||
ref="roleAuthority"
|
||||
:dialog-visible="roleAuthorityDialog.isVisible"
|
||||
@close="roleAuthorityClose"
|
||||
@success="roleAuthoritySuccess"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from "@/components/Pagination"
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import RoleEdit from "./Edit"
|
||||
import UserRole from "./UserRole"
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import RoleAuthority from "./RoleAuthority"
|
||||
import roleApi from "@/api/Role.js"
|
||||
import { convertEnum } from '@/utils/utils'
|
||||
import { downloadFile, initEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "RoleManage",
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, RoleEdit, UserRole, RoleAuthority, FileImport },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
false: "danger",
|
||||
true: "success"
|
||||
}
|
||||
return map[status] || "success"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: "add"
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/authority/role/import`
|
||||
},
|
||||
userRoleDialog: {
|
||||
isVisible: false
|
||||
},
|
||||
roleAuthorityDialog: {
|
||||
isVisible: false
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {
|
||||
dsType: {
|
||||
code: null
|
||||
}
|
||||
}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: {
|
||||
DataScopeType: {}
|
||||
},
|
||||
dicts: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dsTypeList() {
|
||||
return convertEnum(this.enums.DataScopeType)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initEnums('DataScopeType', this.enums)
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
userRoleClose() {
|
||||
this.userRoleDialog.isVisible = false
|
||||
},
|
||||
roleAuthorityClose() {
|
||||
this.roleAuthorityDialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
userRoleSuccess() {
|
||||
this.search()
|
||||
},
|
||||
roleAuthoritySuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {
|
||||
dsType: {
|
||||
code: null
|
||||
}
|
||||
}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出角色数据'
|
||||
roleApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出角色数据'
|
||||
roleApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
roleApi.delete({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = "add"
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setRole({ enums: this.enums })
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setRole({ row, enums: this.enums })
|
||||
this.dialog.type = "edit"
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
roleApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
},
|
||||
authResource(row) {
|
||||
this.roleAuthorityDialog.isVisible = true
|
||||
this.$refs.roleAuthority.setRoleAuthority(row)
|
||||
},
|
||||
authUser(row) {
|
||||
this.userRoleDialog.isVisible = true
|
||||
this.$refs.userRole.setUserRole(row)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,398 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:title="title"
|
||||
:visible.sync="isVisible"
|
||||
:width="width"
|
||||
top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="roleAuthority"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-scrollbar style="height:800px">
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="8">
|
||||
<el-card class="box-card">
|
||||
<el-form-item label="菜单" prop="menuIdList">
|
||||
<div align="left" style="margin-left:24px;">
|
||||
<el-checkbox
|
||||
v-model="checkedMenu"
|
||||
:indeterminate="isIndeterminate"
|
||||
@change="checkedAll"
|
||||
/>
|
||||
全选/反选
|
||||
</div>
|
||||
<el-tree
|
||||
ref="menuTree"
|
||||
:check-strictly="true"
|
||||
:data="menuTree"
|
||||
:default-checked-keys="roleAuthority.menuIdList"
|
||||
:default-expanded-keys="roleAuthority.menuIdList"
|
||||
:disabled="disabled"
|
||||
:expand-on-click-node="false"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
@check="checkMenu"
|
||||
@node-click="nodeClick"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-card class="box-card">
|
||||
<el-form-item label="资源" prop="resourceIdList">
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id"
|
||||
style="width: 100%;"
|
||||
@select="onSelect"
|
||||
@select-all="onAllSelect"
|
||||
>
|
||||
<el-table-column
|
||||
:reserve-selection="true"
|
||||
align="center"
|
||||
type="selection"
|
||||
width="40px"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="$t('table.resource.code')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="code"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.resource.name')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-scrollbar>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{
|
||||
$t("common.cancel")
|
||||
}}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="disabled"
|
||||
plain
|
||||
type="primary"
|
||||
@click="submitForm"
|
||||
>{{ $t("common.confirm") }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roleApi from "@/api/Role.js"
|
||||
import menuApi from "@/api/Menu.js"
|
||||
import resourceApi from "@/api/Resource.js"
|
||||
|
||||
export default {
|
||||
name: "RoleAuthorityEdit",
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
roleAuthority: this.initRoleAuthority(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
menuTree: [],
|
||||
resourceList: [],
|
||||
// 回显的数据
|
||||
echoResourceIdList: [],
|
||||
rules: {},
|
||||
tableKey: 0,
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
selection: [],
|
||||
disabled: false,
|
||||
isIndeterminate: false,
|
||||
checkedMenu: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return "配置菜单资源"
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted() {
|
||||
this.initMenuTree()
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
allMenuIdList() {
|
||||
const menuIdList = []
|
||||
this.getMenuIdList(this.menuTree, menuIdList)
|
||||
return menuIdList
|
||||
},
|
||||
getMenuIdList(menuList, menuIdList) {
|
||||
if (menuList) {
|
||||
menuList.forEach(item => {
|
||||
menuIdList.push(item.id)
|
||||
if (item.children && item.children.length > 0) {
|
||||
this.getMenuIdList(item.children, menuIdList)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
checkedAll() {
|
||||
if (this.checkedMenu) {
|
||||
// 全选
|
||||
this.$refs.menuTree.setCheckedKeys(this.allMenuIdList())
|
||||
this.isIndeterminate = false
|
||||
} else {
|
||||
// 取消选中
|
||||
this.$refs.menuTree.setCheckedKeys([])
|
||||
this.isIndeterminate = false
|
||||
}
|
||||
},
|
||||
nodeClick(data) {
|
||||
const vm = this
|
||||
vm.loading = true
|
||||
|
||||
resourceApi
|
||||
.page({
|
||||
current: 1, size: 10000,
|
||||
model: { menuId: data.id }
|
||||
})
|
||||
.then(response => {
|
||||
const res = response.data
|
||||
vm.tableData = res.data
|
||||
vm.loading = false
|
||||
vm.displayTable()
|
||||
})
|
||||
},
|
||||
displayTable() {
|
||||
const vm = this
|
||||
vm.tableData.records.forEach(item => {
|
||||
vm.roleAuthority.resourceIdList.forEach(resourceId => {
|
||||
if (item.id === resourceId) {
|
||||
vm.$refs.table.toggleRowSelection(item, true)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onAllSelect(selection) {
|
||||
this.onSelect(selection)
|
||||
},
|
||||
onSelect(selection, row) {
|
||||
this.mergeResourceIdList(selection, row)
|
||||
// this.roleAuthority.resourceIdList = selection.map(item => item.id);
|
||||
this.selection = selection
|
||||
|
||||
// 根据右侧选中的资源,强制勾选左侧的 树状层级菜单
|
||||
const old = this.$refs.menuTree.getCheckedKeys()
|
||||
const must = selection.map(item => item.menuId)
|
||||
const newSelected = Array.from(new Set([...old, ...must]))
|
||||
this.$refs.menuTree.setCheckedKeys(newSelected)
|
||||
newSelected.forEach(item => {
|
||||
this.selectedParent(item)
|
||||
})
|
||||
},
|
||||
mergeResourceIdList(selection, row) {
|
||||
// true就是选中,0或者false是取消选中
|
||||
let selected = true
|
||||
if (row) {
|
||||
selected = selection.length && selection.indexOf(row) !== -1
|
||||
} else {
|
||||
selected = selection.length > 0
|
||||
}
|
||||
|
||||
// 本次选中的
|
||||
const curResourceIdList = selection.map(item => item.id)
|
||||
|
||||
const ridList = this.echoResourceIdList
|
||||
if (!selected && row) {
|
||||
var index = ridList.findIndex(item => {
|
||||
if (item == row.id) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
ridList.splice(index, 1)
|
||||
}
|
||||
|
||||
// 本次选中的 + 回显的 然后去重
|
||||
this.roleAuthority.resourceIdList = [
|
||||
...new Set([...curResourceIdList, ...ridList])
|
||||
]
|
||||
},
|
||||
|
||||
initMenuTree() {
|
||||
menuApi.allTree().then(response => {
|
||||
const res = response.data
|
||||
this.menuTree = res.data
|
||||
})
|
||||
},
|
||||
initRoleAuthority() {
|
||||
return {
|
||||
roleId: "",
|
||||
menuIdList: [],
|
||||
resourceIdList: []
|
||||
}
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return "90%"
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return "45%"
|
||||
} else {
|
||||
return "1000px"
|
||||
}
|
||||
},
|
||||
setRoleAuthority(val) {
|
||||
const vm = this
|
||||
vm.roleAuthority.roleId = val.id
|
||||
// vm.disabled = val.readonly
|
||||
// 回显
|
||||
roleApi.findAuthorityIdByRoleId(val.id).then(response => {
|
||||
const res = response.data
|
||||
vm.roleAuthority.menuIdList = res.data.menuIdList
|
||||
vm.roleAuthority.resourceIdList = res.data.resourceIdList
|
||||
vm.echoResourceIdList = res.data.resourceIdList
|
||||
vm.$refs.menuTree.setCheckedKeys(res.data.menuIdList)
|
||||
res.data.menuIdList.forEach(item => {
|
||||
vm.selectedParent(item)
|
||||
})
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.$emit("close")
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.roleAuthority = this.initRoleAuthority()
|
||||
this.$refs.menuTree.setCheckedKeys([])
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
|
||||
this.roleAuthority.menuIdList = vm.$refs.menuTree
|
||||
.getHalfCheckedKeys()
|
||||
.concat(vm.$refs.menuTree.getCheckedKeys())
|
||||
|
||||
// 勾选时, 实时计算出来
|
||||
// this.roleAuthority.resourceIdList = vm.selection.map(item => item.id);
|
||||
|
||||
roleApi.saveRoleAuthority(this.roleAuthority).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t("tips.createSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
vm.$emit("success")
|
||||
}
|
||||
})
|
||||
},
|
||||
checkMenu(data, node) {
|
||||
if (node.checkedKeys.length === 0) {
|
||||
// 取消
|
||||
this.checkedMenu = false
|
||||
this.isIndeterminate = false
|
||||
} else if (node.checkedKeys.length === this.allMenuIdList().length) {
|
||||
// 全选
|
||||
this.checkedMenu = true
|
||||
this.isIndeterminate = false
|
||||
} else {
|
||||
// 中立
|
||||
this.checkedMenu = false
|
||||
this.isIndeterminate = true
|
||||
}
|
||||
|
||||
// 用于:父子节点严格互不关联时,父节点勾选变化时通知子节点同步变化,实现单向关联。
|
||||
const selected = node.checkedKeys.indexOf(data.id) // -1未选中
|
||||
// 选中
|
||||
if (selected !== -1) {
|
||||
// 子节点只要被选中父节点就被选中
|
||||
this.selectedParent(data)
|
||||
// 统一处理子节点为相同的勾选状态
|
||||
this.uniteChildSame(data, true)
|
||||
} else {
|
||||
// 未选中 处理子节点全部未选中
|
||||
if (data.children && data.children.length !== 0) {
|
||||
this.uniteChildSame(data, false)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 统一处理子节点为相同的勾选状态
|
||||
uniteChildSame(data, isSelected) {
|
||||
this.$refs.menuTree.setChecked(data.id, isSelected)
|
||||
if (data.children) {
|
||||
for (let i = 0; i < data.children.length; i++) {
|
||||
this.uniteChildSame(data.children[i], isSelected)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 统一处理父节点为选中
|
||||
selectedParent(data) {
|
||||
const currentNode = this.$refs.menuTree.getNode(data)
|
||||
if (currentNode.parent.key !== undefined) {
|
||||
this.$refs.menuTree.setChecked(currentNode.parent, true)
|
||||
this.selectedParent(currentNode.parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :title="title" :visible.sync="isVisible"
|
||||
:width="width"
|
||||
top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="userRole" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="用户" prop="userIdList">
|
||||
<el-transfer
|
||||
v-model="userRole.userIdList"
|
||||
:data="userList"
|
||||
:filter-method="filterMethod"
|
||||
:props="{
|
||||
key: 'id',
|
||||
label: 'name'
|
||||
}"
|
||||
:render-content="renderFunc"
|
||||
:right-default-checked="userRole.userIdList"
|
||||
:titles="['全部用户', '已选用户']"
|
||||
filter-placeholder="用户名"
|
||||
filterable
|
||||
style="text-align: left; display: inline-block"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button :disabled="disabled" plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roleApi from '@/api/Role.js'
|
||||
import userApi from '@/api/User.js'
|
||||
|
||||
export default {
|
||||
name: 'UserRoleEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
userRole: this.initUserRole(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
userList: [],
|
||||
userIdList: [],
|
||||
disabled: false,
|
||||
rules: {
|
||||
|
||||
},
|
||||
renderFunc (h, option) {
|
||||
// return <span title='option.account - {option.name}'>{option.account} - {option.name}</span>
|
||||
return h("span", {
|
||||
"attrs": {
|
||||
"title": option.account + " - " + option.name
|
||||
}
|
||||
}, [option.account, " - ", option.name])
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return '分配角色成员'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
this.initUserList()
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initUserRole () {
|
||||
return {
|
||||
roleId: '',
|
||||
userIdList: []
|
||||
}
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
initUserList () {
|
||||
userApi.page({ current: 1, size: 100000, model: { status: true }})
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
|
||||
this.userList = res.data.records
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
message: this.$t('tips.getDataFail'),
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
},
|
||||
setUserRole (val) {
|
||||
const vm = this
|
||||
vm.userRole.roleId = val.id
|
||||
// vm.disabled = val.readonly
|
||||
roleApi.findUserIdByRoleId(val.id)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
vm.userRole.userIdList = res.data
|
||||
})
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.userRole = this.initUserRole()
|
||||
this.disabled = false
|
||||
},
|
||||
submitForm () {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const vm = this
|
||||
console.log(this.userRole)
|
||||
|
||||
roleApi.saveUserRole(this.userRole)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
filterMethod (query, item) {
|
||||
return item.name.indexOf(query) > -1 || item.account.indexOf(query) > -1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,393 @@
|
||||
<template>
|
||||
<div class="area">
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="label"
|
||||
:placeholder="$t('table.area.label')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
plain
|
||||
type="primary"
|
||||
@click="search"
|
||||
>{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-has-permission="['area:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="[ 'area:delete', 'area:export']"
|
||||
class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-has-permission="['area:delete']"
|
||||
@click.native="deleteArea"
|
||||
>{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-tree
|
||||
ref="areaTree"
|
||||
:check-strictly="true"
|
||||
:data="areaTree"
|
||||
:filter-node-method="filterNode"
|
||||
:load="loadTree"
|
||||
highlight-current
|
||||
node-key="id"
|
||||
:lazy="true"
|
||||
show-checkbox
|
||||
@node-click="nodeClick"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{
|
||||
area.id === "" ? this.$t("common.add") : this.$t("common.edit")
|
||||
}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="area"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item
|
||||
:hidden="true"
|
||||
:label="$t('table.area.parentId')"
|
||||
prop="parentId"
|
||||
>
|
||||
<el-tooltip
|
||||
:content="$t('tips.topId')"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-input v-model="area.parentId" readonly />
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('table.area.parentId')"
|
||||
prop="parentLabel"
|
||||
>
|
||||
<el-input
|
||||
v-model="area.parentLabel"
|
||||
readonly
|
||||
disabled="disabled"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.area.label')" prop="label">
|
||||
<el-input v-model="area.label" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.area.code')" prop="code">
|
||||
<el-input v-model="area.code" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.area.fullName')" prop="fullName">
|
||||
<el-input v-model="area.fullName" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('table.area.longitude')"
|
||||
prop="longitude"
|
||||
>
|
||||
<el-input v-model="area.longitude" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.area.latitude')" prop="latitude">
|
||||
<el-input v-model="area.latitude" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.area.source')" prop="source">
|
||||
<el-input v-model="area.source" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.area.level')" prop="level">
|
||||
<el-radio-group
|
||||
v-model="area.level.key"
|
||||
border="true"
|
||||
size="small"
|
||||
>
|
||||
<el-radio-button v-for="(item, key, index) in dicts.AREA_LEVEL" :key="index" :label="item" :value="key">
|
||||
{{ item }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:label="$t('table.area.sortValue')"
|
||||
prop="sortValue"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="area.sortValue"
|
||||
:max="100"
|
||||
:min="0"
|
||||
@change="handleNumChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top: -2rem;">
|
||||
<el-row>
|
||||
<el-col :span="24" style="text-align: right">
|
||||
<el-button plain type="primary" @click="submit">{{
|
||||
area.id === "" ? this.$t("common.add") : this.$t("common.edit")
|
||||
}}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import areaApi from "@/api/Area.js"
|
||||
import { initDicts } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "AreaManager",
|
||||
data() {
|
||||
return {
|
||||
label: "",
|
||||
areaTree: [],
|
||||
dicts: { AREA_LEVEL: {}},
|
||||
area: this.initArea(),
|
||||
rules: {
|
||||
label: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 255,
|
||||
message: this.$t("rules.range3to10"),
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 255,
|
||||
message: this.$t("rules.range3to10"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
areaApi.check(value, this.area.id).then(response => {
|
||||
const res = response.data
|
||||
if (res.data) {
|
||||
callback('编码重复')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}).catch(() => callback())
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initDicts('AREA_LEVEL', this.dicts)
|
||||
},
|
||||
methods: {
|
||||
initArea() {
|
||||
return {
|
||||
id: "",
|
||||
code: "",
|
||||
label: "",
|
||||
parentId: 0,
|
||||
parentLabel: "",
|
||||
fullName: "",
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
source: "",
|
||||
level: {
|
||||
key: "PROVINCE"
|
||||
},
|
||||
sortValue: 0
|
||||
}
|
||||
},
|
||||
initAreaTree(parentId = 0) {
|
||||
areaApi.query({ parentId: parentId }).then(response => {
|
||||
const res = response.data
|
||||
this.areaTree = res.data
|
||||
})
|
||||
},
|
||||
loadTree(node, resolve) {
|
||||
areaApi.query({ parentId: node.data.id }).then(response => {
|
||||
const res = response.data
|
||||
resolve(res.data)
|
||||
})
|
||||
},
|
||||
handleNumChange(val) {
|
||||
this.area.sortValue = val
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
},
|
||||
nodeClick(data) {
|
||||
this.area = { ...data }
|
||||
|
||||
const parent = this.$refs.areaTree.getNode(data.parentId)
|
||||
if (parent) {
|
||||
this.area.parentLabel = parent.label
|
||||
}
|
||||
|
||||
this.$refs.form.clearValidate()
|
||||
},
|
||||
add() {
|
||||
this.resetForm()
|
||||
const checked = this.$refs.areaTree.getCheckedNodes()
|
||||
if (checked.length > 1) {
|
||||
this.$message({
|
||||
message: this.$t("tips.onlyChooseOne"),
|
||||
type: "warning"
|
||||
})
|
||||
} else if (checked.length > 0) {
|
||||
this.area.parentId = checked[0].id
|
||||
this.area.parentLabel = checked[0].label
|
||||
} else {
|
||||
this.area.parentId = 0
|
||||
this.area.parentLabel = ""
|
||||
}
|
||||
},
|
||||
deleteArea() {
|
||||
const checked = this.$refs.areaTree.getCheckedKeys()
|
||||
if (checked.length === 0) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noNodeSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
} else {
|
||||
this.$confirm(
|
||||
this.$t("tips.confirmDeleteNode"),
|
||||
this.$t("common.tips"),
|
||||
{
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
areaApi.delete({ ids: checked }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.$refs.areaTree.setCheckedKeys([])
|
||||
})
|
||||
}
|
||||
},
|
||||
search() {
|
||||
this.$refs.areaTree.filter(this.label)
|
||||
},
|
||||
reset() {
|
||||
this.initAreaTree()
|
||||
this.label = ""
|
||||
this.resetForm()
|
||||
},
|
||||
submit() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
if (this.area.id) {
|
||||
this.update()
|
||||
} else {
|
||||
this.save()
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
save() {
|
||||
areaApi.save({ ...this.area }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.createSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
update() {
|
||||
areaApi.update({ ...this.area }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.updateSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.area = this.initArea()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.area {
|
||||
margin: 10px;
|
||||
|
||||
.app-container {
|
||||
margin: 0 0 10px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
|
||||
.el-card__header {
|
||||
padding: 10px 20px !important;
|
||||
border-bottom: 1px solid #f1f1f1 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.type" :placeholder="$t('table.dictionary.type')" size="small"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.name" :placeholder="$t('table.dictionary.name')" size="small"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-button
|
||||
class="filter-item" plain type="primary"
|
||||
size="small"
|
||||
@click="search"
|
||||
>{{ $t('table.search') }}</el-button>
|
||||
<el-button
|
||||
class="filter-item" plain type="warning"
|
||||
size="small"
|
||||
@click="reset"
|
||||
>{{ $t('table.reset') }}</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['dict:delete','dict:export', 'dict:import']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button size="small">
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['dict:add']" @click.native="add">
|
||||
{{ $t('table.add') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['dict:delete']" @click.native="batchDelete">
|
||||
{{ $t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" size="mini" style="width: 100%;"
|
||||
@filter-change="filterChange"
|
||||
@row-click="rowClick"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column :label="$t('table.dictionary.type')" :show-overflow-tooltip="true" align="center" prop="type">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.type }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.dictionary.name')" :show-overflow-tooltip="true" align="center" prop="name">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.dictionary.describe')" :show-overflow-tooltip="true" align="center"
|
||||
prop="describe"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
column-key="status"
|
||||
:filters="[{ text: $t('common.status.valid'), value: true }, { text: $t('common.status.invalid'), value: false }]"
|
||||
:label="$t('table.dictionary.status')"
|
||||
class-name="status-col"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<el-tag :type="row.status | statusFilter">{{ row.status ? $t('common.status.valid') :
|
||||
$t('common.status.invalid') }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" align="center" prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" align="center" class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-hasPermission="['dict:update']" class="el-icon-edit table-operation" style="color: #2db7f5;"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['dict:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link v-has-no-permission="['dict:update','dict:delete']" class="no-perm">{{ $t('tips.noPermission') }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
<dictionary-edit
|
||||
ref="edit" :dialog-visible="dialog.isVisible" :type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import DictionaryEdit from './Edit'
|
||||
import dictionaryApi from '@/api/Dictionary.js'
|
||||
import { initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'DictionaryManage',
|
||||
components: { Pagination, DictionaryEdit },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
false: 'danger',
|
||||
true: 'success'
|
||||
}
|
||||
return map[status] || 'success'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
mounted() {
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
this.$emit('dictionaryClick', { id: -1 })
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach((u) => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
dictionaryApi.delete({ 'ids': ids })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = 'add'
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setDictionary(false)
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setDictionary(row)
|
||||
this.dialog.type = 'edit'
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
dictionaryApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
rowClick(row) {
|
||||
this.$emit('dictionaryClick', row)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,394 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div v-if="queryParams.dictionaryId === -1">
|
||||
<div class="my-code">点击字典查看详情</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.code" :placeholder="$t('table.dictionaryItem.code')" size="small"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.name" :placeholder="$t('table.dictionaryItem.name')" size="small"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-button
|
||||
class="filter-item" plain type="primary"
|
||||
size="small"
|
||||
@click="search"
|
||||
>{{ $t('table.search') }}</el-button>
|
||||
<el-button
|
||||
class="filter-item" plain type="warning"
|
||||
size="small"
|
||||
@click="reset"
|
||||
>{{ $t('table.reset') }}</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['dict:add','dict:delete','dict:export']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button size="small">
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['dict:add']" @click.native="add">{{ $t('table.add') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['dict:delete']" @click.native="batchDelete">{{ $t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['dict:export']" @click.native="exportExcel">{{ $t('table.export') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['dict:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['dict:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-table
|
||||
:key="tableKey" ref="table" v-loading="loading"
|
||||
:data="tableData.records" border fit
|
||||
row-key="id" size="mini" style="width: 100%;"
|
||||
@selection-change="onSelectChange" @sort-change="sortChange" @cell-click="cellClick"
|
||||
@filter-change="filterChange"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.dictionaryItem.code')" :show-overflow-tooltip="true" align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.dictionaryItem.name')" :show-overflow-tooltip="true" align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.dictionaryItem.describe')" :show-overflow-tooltip="true" align="center"
|
||||
prop="describe"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
column-key="status"
|
||||
:filter-multiple="false"
|
||||
:filters="[{ text: $t('common.status.valid'), value: true }, { text: $t('common.status.invalid'), value: false }]"
|
||||
:label="$t('table.dictionaryItem.status')"
|
||||
class-name="status-col"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<el-tag :type="row.status | statusFilter">{{ row.status ? $t('common.status.valid') :
|
||||
$t('common.status.invalid') }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" align="center" prop="createTime"
|
||||
sortable="custom"
|
||||
width="160px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" column-key="operation" sortable="custom"
|
||||
align="center" class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-hasPermission="['dict:update']" class="el-icon-edit table-operation" style="color: #2db7f5;"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['dict:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link v-has-no-permission="['dict:update','dict:delete']" class="no-perm">{{ $t('tips.noPermission') }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
<dictionaryItem-edit
|
||||
ref="edit" :dialog-visible="dialog.isVisible" :type="dialog.type"
|
||||
@close="editClose" @success="editSuccess"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import DictionaryItemEdit from './DictionaryItemEdit'
|
||||
import dictionaryItemApi from '@/api/DictionaryItem.js'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import { downloadFile, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'DictionaryItemManage',
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, DictionaryItemEdit, FileImport },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
false: 'danger',
|
||||
true: 'success'
|
||||
}
|
||||
return map[status] || 'success'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/authority/dictionaryItem/import`
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {
|
||||
dictionaryId: -1
|
||||
},
|
||||
sort: 'sortValue',
|
||||
order: 'ascending'
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
dictionary: {
|
||||
id: null,
|
||||
code: ''
|
||||
},
|
||||
tableData: {
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
mounted() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: { dictionaryId: this.dictionary.id }
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出字典数据'
|
||||
dictionaryItemApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出字典数据'
|
||||
dictionaryItemApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach((u) => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
dictionaryItemApi.delete({ 'ids': ids })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = 'add'
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setDictionaryItem({
|
||||
id: null,
|
||||
status: true,
|
||||
dictionaryId: this.dictionary.id,
|
||||
dictionaryType: this.dictionary.type
|
||||
})
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setDictionaryItem(row)
|
||||
this.dialog.type = 'edit'
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
dictionaryItemApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
},
|
||||
dictionaryClick(dictionary) {
|
||||
this.queryParams.model.dictionaryId = dictionary.id
|
||||
this.dictionary = dictionary
|
||||
this.search()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :close-on-press-escape="true" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="dictionaryItem" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :hidden="true" :label="$t('table.dictionaryItem.dictionaryId')" prop="dictionaryId">
|
||||
<el-input v-model="dictionaryItem.dictionaryId" :disabled="type==='edit'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionaryItem.code')" prop="code">
|
||||
<el-input v-model="dictionaryItem.code" :disabled="type==='edit'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionaryItem.name')" prop="name">
|
||||
<el-input v-model="dictionaryItem.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionaryItem.status')" prop="status">
|
||||
<el-radio-group v-model="dictionaryItem.status">
|
||||
<el-radio :label="true">{{ $t('common.status.valid') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('common.status.invalid') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionaryItem.sortValue')" prop="sortValue">
|
||||
<el-input v-model="dictionaryItem.sortValue" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionaryItem.describe')" prop="describe">
|
||||
<el-input v-model="dictionaryItem.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import dictionaryItemApi from '@/api/DictionaryItem.js'
|
||||
|
||||
export default {
|
||||
name: 'DictionaryItemEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dictionaryItem: this.initDictionaryItem(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
rules: {
|
||||
dictionaryId: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
code: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 64, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 64, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
describe: [
|
||||
{ min: 1, max: 200, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
status: { required: true, message: this.$t('rules.require'), trigger: 'blur' }
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return this.type === 'add' ? this.$t('common.add') : this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initDictionaryItem () {
|
||||
return {
|
||||
id: '',
|
||||
dictionaryId: null,
|
||||
dictionaryType: '',
|
||||
name: '',
|
||||
code: '',
|
||||
status: true,
|
||||
sortValue: 1,
|
||||
describe: ''
|
||||
}
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
setDictionaryItem (val) {
|
||||
const vm = this
|
||||
if (val) {
|
||||
vm.dictionaryItem = { ...val }
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.dictionaryItem = this.initDictionaryItem()
|
||||
},
|
||||
submitForm () {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const vm = this
|
||||
if (vm.type === 'add') {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const vm = this
|
||||
dictionaryItemApi.save(this.dictionaryItem)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
dictionaryItemApi.update(this.dictionaryItem)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :close-on-press-escape="true" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="dictionary" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.dictionary.type')" prop="type">
|
||||
<el-input v-model="dictionary.type" :disabled="type==='edit'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionary.name')" prop="name">
|
||||
<el-input v-model="dictionary.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionary.status')" prop="status">
|
||||
<el-radio-group v-model="dictionary.status">
|
||||
<el-radio :label="true">{{ $t('common.status.valid') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('common.status.invalid') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.dictionary.describe')" prop="describe">
|
||||
<el-input v-model="dictionary.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import dictionaryApi from '@/api/Dictionary.js'
|
||||
|
||||
export default {
|
||||
name: 'DictionaryEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dictionary: this.initDictionary(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
rules: {
|
||||
type: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 64, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 64, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
describe: [
|
||||
{ min: 1, max: 200, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
status: { required: true, message: this.$t('rules.require'), trigger: 'blur' }
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return this.type === 'add' ? this.$t('common.add') : this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initDictionary () {
|
||||
return {
|
||||
id: '',
|
||||
name: '',
|
||||
type: '',
|
||||
status: true,
|
||||
describe: ''
|
||||
}
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
setDictionary (val) {
|
||||
const vm = this
|
||||
if (val) {
|
||||
vm.dictionary = { ...val }
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.dictionary = this.initDictionary()
|
||||
},
|
||||
submitForm () {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const vm = this
|
||||
if (vm.type === 'add') {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const vm = this
|
||||
dictionaryApi.save(this.dictionary)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
dictionaryApi.update(this.dictionary)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>字典列表</span>
|
||||
</div>
|
||||
<dictionary ref="dictionary" @dictionaryClick="dictionaryClick" @resetItem="resetItem" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>字典详情</span>
|
||||
</div>
|
||||
<dictionary-item ref="dictionaryItem" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dictionary from './Dictionary'
|
||||
import DictionaryItem from './DictionaryItem'
|
||||
|
||||
export default {
|
||||
name: 'DictionaryManage',
|
||||
components: { Dictionary, DictionaryItem },
|
||||
filters: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
|
||||
},
|
||||
methods: {
|
||||
dictionaryClick (row) {
|
||||
this.$refs.dictionaryItem.dictionaryClick(row)
|
||||
},
|
||||
resetItem () {
|
||||
this.$refs.dictionaryItem.dictionaryClick({ id: -1 })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-card /deep/ .el-card__body {
|
||||
padding: 0px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
:title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible"
|
||||
:width="width"
|
||||
top="50px"
|
||||
>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">
|
||||
{{ $t("common.cancel") }}
|
||||
</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">
|
||||
{{ $t("common.confirm") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-form
|
||||
ref="form" :model="parameter" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.parameter.key')" prop="key">
|
||||
<el-input v-model="parameter.key" :disabled="type==='edit'" type="" placeholder="参数键" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.parameter.name')" prop="name">
|
||||
<el-input v-model="parameter.name" type="" placeholder="参数名称" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.parameter.value')" prop="value">
|
||||
<el-input v-model="parameter.value" type="" placeholder="参数值" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.parameter.describe')" prop="describe">
|
||||
<el-input v-model="parameter.describe" type="textarea" placeholder="描述" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.parameter.status')" prop="status">
|
||||
<el-radio-group v-model="parameter.status" size="medium">
|
||||
<el-radio-button :label="true">{{ $t("common.status.valid") }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t("common.status.invalid") }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.parameter.readonly')" prop="readonly">
|
||||
<el-radio-group v-model="parameter.readonly" size="medium">
|
||||
<el-radio-button :label="true">{{ $t("common.yes") }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t("common.no") }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import parameterApi from "@/api/Parameter.js"
|
||||
|
||||
export default {
|
||||
name: "ParameterEdit",
|
||||
components: { },
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "add"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
parameter: this.initParameter(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
rules: {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return this.$t("common." + this.type)
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted() {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initParameter() {
|
||||
return {
|
||||
id: "",
|
||||
key: '',
|
||||
name: '',
|
||||
value: '',
|
||||
describe: '',
|
||||
status: true,
|
||||
readonly: false
|
||||
}
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return "90%"
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return "45%"
|
||||
} else {
|
||||
return "800px"
|
||||
}
|
||||
},
|
||||
setParameter(val) {
|
||||
const vm = this
|
||||
if (val) {
|
||||
vm.parameter = { ...val }
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit("close")
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.parameter = this.initParameter()
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
if (vm.type === "edit") {
|
||||
vm.update()
|
||||
} else {
|
||||
vm.save()
|
||||
}
|
||||
},
|
||||
save() {
|
||||
const vm = this
|
||||
parameterApi.save(this.parameter).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t("tips.createSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
vm.$emit("success")
|
||||
}
|
||||
})
|
||||
},
|
||||
update() {
|
||||
parameterApi.update(this.parameter).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t("tips.updateSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
this.$emit("success")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,418 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
|
||||
<el-input
|
||||
v-model="queryParams.model.key"
|
||||
:placeholder="$t('table.parameter.key')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.name"
|
||||
:placeholder="$t('table.parameter.name')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.value"
|
||||
:placeholder="$t('table.parameter.value')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">
|
||||
{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-has-permission="['parameter:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['parameter:delete', 'parameter:export', 'parameter:import']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['parameter:delete']" @click.native="batchDelete">
|
||||
{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['parameter:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['parameter:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['parameter:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.parameter.key')" :show-overflow-tooltip="true" align="center"
|
||||
prop="key" width=""
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.key }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.parameter.name')" :show-overflow-tooltip="true" align="center"
|
||||
prop="name" width=""
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.parameter.value')" :show-overflow-tooltip="true" align="center"
|
||||
prop="value" width=""
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.value }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.parameter.describe')" :show-overflow-tooltip="true" align="center"
|
||||
prop="describe" width=""
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.parameter.status')" :show-overflow-tooltip="true" align="center"
|
||||
:filter-multiple="false" column-key="status"
|
||||
:filters="[{ text: $t('common.status.valid'), value: true },{ text: $t('common.status.invalid'), value: false }]"
|
||||
prop="status" width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tag slot :type="scope.row.status ? 'success' : 'danger'">
|
||||
{{ scope.row.status ? $t("common.status.valid") : $t("common.status.invalid") }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.parameter.readonly')" :show-overflow-tooltip="true" align="center"
|
||||
:filter-multiple="false" column-key="readonly"
|
||||
:filters="[{ text: $t('common.yes'), value: 'true' }, { text: $t('common.no'), value: 'false' }]"
|
||||
prop="readonly" width="70px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tag slot :type="scope.row.readonly ? 'success' : 'danger'">
|
||||
{{ scope.row.readonly ? $t("common.yes") : $t("common.no") }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" column-key="operation" align="center"
|
||||
class-name="small-padding fixed-width" width="100px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-hasPermission="['parameter:add']" class="el-icon-copy-document table-operation" :title="$t('common.delete')"
|
||||
style="color: #2db7f5;" @click="copy(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['parameter:update']" class="el-icon-edit table-operation" :title="$t('common.delete')"
|
||||
style="color: #2db7f5;" @click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['parameter:delete']" class="el-icon-delete table-operation" :title="$t('common.delete')"
|
||||
style="color: #f50;" @click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link v-has-no-permission="['parameter:update', 'parameter:add', 'parameter:delete']" class="no-perm">
|
||||
{{ $t("tips.noPermission") }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<parameter-edit
|
||||
ref="edit"
|
||||
:dialog-visible="dialog.isVisible"
|
||||
:type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from "@/components/Pagination"
|
||||
import ParameterEdit from "./Edit"
|
||||
import parameterApi from "@/api/Parameter.js"
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import { downloadFile, initDicts, initEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "ParameterManage",
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, ParameterEdit, FileImport },
|
||||
filters: {},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: "add"
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/authority/parameter/import`
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
mounted() {
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出参数数据'
|
||||
parameterApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出参数数据'
|
||||
parameterApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = this.selection.map(u => u.id)
|
||||
this.delete(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
parameterApi.delete({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = "add"
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setParameter(false)
|
||||
},
|
||||
copy(row) {
|
||||
this.$refs.edit.setParameter(row)
|
||||
this.dialog.type = "copy"
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setParameter(row)
|
||||
this.dialog.type = "edit"
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
parameterApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :close-on-press-escape="true" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="application" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item v-show="type!=='add' " :label="$t('table.application.clientId')" prop="clientId">
|
||||
<el-input v-model="application.clientId" :disabled="type==='view' || type==='edit' " />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="type!=='add' " :label="$t('table.application.clientSecret')" prop="clientSecret">
|
||||
<el-input v-model="application.clientSecret" :disabled="type==='view' || type==='edit' " />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.application.name')" prop="name">
|
||||
<el-input v-model="application.name" :disabled="type==='view'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.application.website')" prop="website">
|
||||
<el-input v-model="application.website" :disabled="type==='view'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.application.icon')" prop="icon">
|
||||
<el-input v-model="application.icon" :disabled="type==='icon'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.application.appType')" prop="appType">
|
||||
<el-radio-group v-model="application.appType.code" border="true" size="small">
|
||||
<el-radio-button
|
||||
v-for="(item, key, index) in enums.ApplicationAppTypeEnum" :key="index" :label="key"
|
||||
:value="key"
|
||||
>{{ item }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.application.status')" prop="status">
|
||||
<el-radio-group v-model="application.status" border="true" size="small">
|
||||
<el-radio-button :label="true">{{ $t('common.status.valid') }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t('common.status.invalid') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<aside class="tips">禁用:提示"请求地址,禁止访问!";</aside>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.application.describe')" prop="describe">
|
||||
<el-input v-model="application.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
import applicationApi from '@/api/Application.js'
|
||||
import { initEnums } from '@/utils/commons.js'
|
||||
|
||||
export default {
|
||||
name: 'ApplicationEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
remoteApplicationLoading: false,
|
||||
application: this.initApplication(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
orgList: [],
|
||||
enums: { ApplicationAppTypeEnum: {}},
|
||||
applicationList: [],
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
status: { required: true, message: this.$t('rules.require'), trigger: 'blur' }
|
||||
|
||||
},
|
||||
serviceList: [
|
||||
{ id: "ceres-authority-server", name: "权限服务" },
|
||||
{ id: "ceres-file-server", name: "文件服务" },
|
||||
{ id: "ceres-msgs-server", name: "消息服务" },
|
||||
{ id: "ceres-demo-server", name: "演示服务" },
|
||||
{ id: "ceres-order-server", name: "订单服务" }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return this.type === 'add' ? this.$t('common.add') : this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted() {
|
||||
initEnums(['ApplicationAppTypeEnum'], this.enums)
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initApplication() {
|
||||
return {
|
||||
id: '',
|
||||
clientId: '',
|
||||
clientSecret: '',
|
||||
website: '',
|
||||
name: '',
|
||||
icon: '',
|
||||
appType: { code: 'SERVER' },
|
||||
describe: '',
|
||||
status: true
|
||||
}
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
loadListOptions({ callback }) {
|
||||
callback()
|
||||
},
|
||||
setApplication(val, orgs) {
|
||||
const vm = this
|
||||
vm.orgList = orgs
|
||||
if (val) {
|
||||
vm.application = { ...val }
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.application = this.initApplication()
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
if (vm.type === 'add') {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save() {
|
||||
const vm = this
|
||||
applicationApi.save(this.application)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update() {
|
||||
applicationApi.update(this.application)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tips {
|
||||
margin-bottom: 0;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,394 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.clientId" :placeholder="$t('table.application.clientId')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.name" :placeholder="$t('table.application.name')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
:start-placeholder="$t('table.createTime')"
|
||||
class="filter-item search-item date-range-item"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t('table.reset') }}</el-button>
|
||||
<el-button
|
||||
v-has-permission="['application:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['application:delete','application:export']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['application:delete']" @click.native="batchDelete">{{ $t('table.delete')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['application:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['application:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @cell-click="cellClick"
|
||||
@filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.application.clientId')" column-key="clientId" :show-overflow-tooltip="true"
|
||||
align="center" prop="clientId"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.clientId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.application.name')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="120px" prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.application.website')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="120px" prop="website"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.website }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.application.appType')" :show-overflow-tooltip="true" align="center"
|
||||
min-width="50px" prop="appType"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.appType ? scope.row.appType.desc : '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.application.status')" :show-overflow-tooltip="true" align="center"
|
||||
prop="status" width="70px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-badge :type="scope.row.status ? 'success' :'danger'" class="status-item" is-dot />
|
||||
<span>{{ scope.row.status? $t('common.status.valid') : $t('common.status.invalid') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.application.describe')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="120px" prop="describe"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" :show-overflow-tooltip="true" sortable="custom"
|
||||
align="center"
|
||||
prop="className" width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" align="center" column-key="operation"
|
||||
class-name="small-padding fixed-width" fixed="right" width="110px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-has-permission="['application:update']" class="el-icon-edit table-operation" style="color: #2db7f5;"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-has-permission="['application:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
|
||||
<application-edit
|
||||
ref="edit" :dialog-visible="dialog.isVisible" :type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import ApplicationEdit from './Edit'
|
||||
import applicationApi from '@/api/Application.js'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import { downloadFile, initQueryParams } from '@/utils/commons'
|
||||
import { copy } from '@/utils/utils'
|
||||
|
||||
export default {
|
||||
name: 'Application',
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, ApplicationEdit },
|
||||
filters: {},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
tableKey: 0,
|
||||
loading: false,
|
||||
queryParams: initQueryParams({
|
||||
model: {}
|
||||
}),
|
||||
selection: [],
|
||||
tableData: {
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出应用数据'
|
||||
applicationApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出应用数据'
|
||||
applicationApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
applicationApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const isPersist = this.selection.findIndex(item => item.isPersist)
|
||||
if (isPersist > -1) {
|
||||
this.$message({
|
||||
message: "不能删除内置数据",
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const logIds = this.selection.map(item => item.id)
|
||||
this.delete(logIds)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(logIds) {
|
||||
applicationApi.delete({ ids: logIds })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
closeDrawer(done) {
|
||||
done()
|
||||
this.currentRow = {}
|
||||
},
|
||||
cellClick(row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
if (column['columnKey'] === "clientId") {
|
||||
copy(row[column.property])
|
||||
this.$message({
|
||||
message: this.$t('tips.copySelected'),
|
||||
type: 'success'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
},
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = 'add'
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setApplication(false)
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setApplication(row)
|
||||
this.dialog.type = 'edit'
|
||||
this.dialog.isVisible = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.box-item {
|
||||
margin-top: 15px;
|
||||
|
||||
aside {
|
||||
word-wrap: break-word;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="权限服务" name="first">
|
||||
<i-frame ref="authorityDruid" :src="authorityDruid" @refresh="authorityRefresh" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="文件服务" name="second">
|
||||
<i-frame ref="fileDruid" :src="fileDruid" @refresh="fileRefresh" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="消息服务" name="third">
|
||||
<i-frame ref="msgsDruid" :src="msgsDruid" @refresh="msgsRefresh" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<script>
|
||||
import iFrame from '@/components/iFrame'
|
||||
import { druid } from '@/settings'
|
||||
|
||||
export default {
|
||||
components: { iFrame },
|
||||
data () {
|
||||
return {
|
||||
authorityDruid: '',
|
||||
fileDruid: '',
|
||||
msgsDruid: '',
|
||||
activeName: 'first'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
setTimeout(() => {
|
||||
this.$notify.info({
|
||||
title: this.$t('common.tips'),
|
||||
message: this.$t('tips.iframeGrant'),
|
||||
duration: 5000
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
this.authorityDruid = this.druidUrl("authority")
|
||||
this.$refs.authorityDruid.url = this.authorityDruid
|
||||
|
||||
this.fileDruid = this.druidUrl("file")
|
||||
this.$refs.fileDruid.url = this.fileDruid
|
||||
|
||||
this.msgsDruid = this.druidUrl("msgs")
|
||||
this.$refs.msgsDruid.url = this.msgsDruid
|
||||
},
|
||||
methods: {
|
||||
authorityRefresh (u) {
|
||||
this.authorityDruid = u
|
||||
},
|
||||
fileRefresh (u) {
|
||||
this.fileDruid = u
|
||||
},
|
||||
msgsRefresh (u) {
|
||||
this.msgsDruid = u
|
||||
},
|
||||
handleClick (tab, event) {
|
||||
console.log(tab, event)
|
||||
},
|
||||
druidUrl (service) {
|
||||
if (druid[service]) {
|
||||
return druid[service][process.env.NODE_ENV]
|
||||
} else {
|
||||
return service
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,433 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.account"
|
||||
:placeholder="$t('table.loginLog.account')" class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.location" :placeholder="$t('table.loginLog.location')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.requestIp"
|
||||
:placeholder="$t('table.loginLog.requestIp')" class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
:start-placeholder="$t('table.createTime')"
|
||||
class="filter-item search-item date-range-item"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">
|
||||
{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['loginLog:delete', 'loginLog:export']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['loginLog:delete']" @click.native="batchDelete">
|
||||
{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['loginLog:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['loginLog:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-dropdown v-has-any-permission="['loginLog:delete']" class="filter-item" trigger="click">
|
||||
<el-button>
|
||||
清理日志
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="clear(1)">
|
||||
保留一个月
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(2)">
|
||||
保留三个月
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(3)">
|
||||
保留六个月
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(4)">
|
||||
保留一年
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(5)">
|
||||
保留一千条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(6)">
|
||||
保留一万条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(7)">
|
||||
保留三万条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(8)">
|
||||
保留十万条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(9)">
|
||||
清空所有
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.userName')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
min-width="80px"
|
||||
prop="userName"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.userName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.requestIp')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
min-width="80px"
|
||||
prop="requestIp"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.requestIp }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.browser')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="browser"
|
||||
width="120px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.browser }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.browserVersion')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="browserVersion"
|
||||
width="120px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.browserVersion }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.operatingSystem')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="operatingSystem"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.operatingSystem }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.location')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
min-width="150px"
|
||||
prop="location"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.location }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.loginDate')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.loginLog.description')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="left"
|
||||
column-key="description"
|
||||
prop="description"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-badge
|
||||
:type="scope.row.description && scope.row.description == '登录成功' ? 'success' : 'danger'"
|
||||
class="item" is-dot
|
||||
/>
|
||||
{{ scope.row.description }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="$t('table.operation')"
|
||||
column-key="operation"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-has-permission="['loginLog:delete']"
|
||||
class="el-icon-delete table-operation"
|
||||
style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
|
||||
<el-link v-has-no-permission="['loginLog:delete']" class="no-perm">{{
|
||||
$t("tips.noPermission")
|
||||
}}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Pagination from "@/components/Pagination"
|
||||
import loginLogApi from "@/api/LoginLog.js"
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import { downloadFile, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "LoginLog",
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination },
|
||||
filters: {},
|
||||
data() {
|
||||
return {
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
tableKey: 0,
|
||||
loading: false,
|
||||
queryParams: initQueryParams(),
|
||||
selection: [],
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: {},
|
||||
dicts: {}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出登录日志数据'
|
||||
loginLogApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出登录日志数据'
|
||||
loginLogApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
loginLogApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
clear(type) {
|
||||
this.$confirm('确认要清除日志吗?', this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
loginLogApi.clear({ type: type }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
|
||||
this.search()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const logIds = this.selection.map(item => item.id)
|
||||
this.delete(logIds)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(logIds) {
|
||||
loginLogApi.delete({ ids: logIds }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams()
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
margin-top: 7px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,513 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.userName" :placeholder="$t('table.optLog.userName')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.requestIp" :placeholder="$t('table.optLog.requestIp')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
:start-placeholder="$t('table.createTime')"
|
||||
class="filter-item search-item date-range-item"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t('table.reset') }}</el-button>
|
||||
<el-dropdown v-has-any-permission="['optLog:delete','optLog:export']" class="filter-item" trigger="click">
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['optLog:delete']" @click.native="batchDelete">{{ $t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['optLog:export']" @click.native="exportExcel">{{ $t('table.export') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['optLog:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-dropdown v-has-any-permission="['optLog:delete']" class="filter-item" trigger="click">
|
||||
<el-button>
|
||||
清理日志
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="clear(1)">
|
||||
保留一个月
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(2)">
|
||||
保留三个月
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(3)">
|
||||
保留六个月
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(4)">
|
||||
保留一年
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(5)">
|
||||
保留一千条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(6)">
|
||||
保留一万条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(7)">
|
||||
保留三万条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(8)">
|
||||
保留十万条
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clear(9)">
|
||||
清空所有
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.userName')" :show-overflow-tooltip="true" align="center"
|
||||
prop="userName"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.userName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.requestUri')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="120px" prop="requestUri"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.requestUri }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="httpMethodFilters"
|
||||
:label="$t('table.optLog.httpMethod')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
column-key="httpMethod"
|
||||
prop="httpMethod"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.httpMethod.desc }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.requestIp')" :show-overflow-tooltip="true" align="center"
|
||||
prop="requestIp" width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.requestIp }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.description')" :show-overflow-tooltip="true" align="center"
|
||||
min-width="100px" prop="description"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.description }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:filter-multiple="false" :filters="typeFilters" :label="$t('table.optLog.type')"
|
||||
:show-overflow-tooltip="true" align="center" column-key="type"
|
||||
prop="type" width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-badge
|
||||
:type="(scope.row.type && scope.row.type.code == 'OPT')? 'success':'danger' " class="item"
|
||||
is-dot
|
||||
/>
|
||||
{{ scope.row.type.desc }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.actionMethod')" :show-overflow-tooltip="true" align="center"
|
||||
min-width="120px" prop="actionMethod"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.classPath + '.' + scope.row.actionMethod }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.startTime')" :show-overflow-tooltip="true" align="center"
|
||||
prop="startTime" sortable="custom" width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.startTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.optLog.consumingTime')" :show-overflow-tooltip="true" align="center"
|
||||
prop="consumingTime" width="110px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<el-tag :type="row.consumingTime | timeFilter">{{ transTime(row.consumingTime) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :formatter="uaForamt" label="终端 | 浏览器" prop="ua" width="120" />
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" column-key="operation" align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
width="110px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-has-permission="['optLog:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<i
|
||||
v-has-permission="['optLog:view']" class="el-icon-view table-operation" style="color: #87d068;"
|
||||
@click="onView(row)"
|
||||
></i>
|
||||
<el-link v-has-no-permission="['optLog:delete','optLog:view']" class="no-perm">{{ $t('tips.noPermission') }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
|
||||
<el-drawer v-model="currentRow" :before-close="closeDrawer" :visible.sync="drawer" direction="rtl">
|
||||
<div slot="title" class="clearfix">
|
||||
<el-badge :type="(currentRow.type && currentRow.type.code == 'OPT')? 'success':'danger' " class="item" is-dot />
|
||||
{{ currentRow.type ? currentRow.type.desc : '' }}
|
||||
{{ currentRow.requestUri }}
|
||||
</div>
|
||||
<el-scrollbar style="height: 100%;">
|
||||
<el-card class="box-card">
|
||||
<div class="box-item">
|
||||
<span class="field-label">执行方法:</span>
|
||||
<aside>{{ currentRow.classPath + '.' + currentRow.actionMethod + '()' }}</aside>
|
||||
</div>
|
||||
|
||||
<div class="box-item">
|
||||
<span class="field-label">请求参数:</span>
|
||||
<aside style>{{ currentRow.params }}</aside>
|
||||
</div>
|
||||
|
||||
<div class="box-item">
|
||||
<span class="field-label">响应信息:</span>
|
||||
<aside style>
|
||||
<pre style="white-space: pre-wrap;">{{ currentRow.result ? JSON.stringify(JSON.parse(currentRow.result), null, 4) : '' }}</pre>
|
||||
</aside>
|
||||
</div>
|
||||
<div v-if="currentRow.type && currentRow.type['code']==='EX'" class="box-item">
|
||||
<span class="field-label">错误信息:</span>
|
||||
<aside>{{ currentRow.exDetail }}</aside>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-scrollbar>
|
||||
</el-drawer>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import { readUserAgent } from '@/utils/utils'
|
||||
import optLogApi from '@/api/OptLog.js'
|
||||
import { convertEnum } from '@/utils/utils'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import { downloadFile, initEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'OptLog',
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination },
|
||||
filters: {
|
||||
timeFilter(time) {
|
||||
if (time < 500) {
|
||||
return 'success'
|
||||
} else if (time < 1000) {
|
||||
return ''
|
||||
} else if (time < 1500) {
|
||||
return 'warning'
|
||||
} else {
|
||||
return 'danger'
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableKey: 0,
|
||||
loading: false,
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
queryParams: initQueryParams({
|
||||
model: {
|
||||
type: {
|
||||
key: null
|
||||
},
|
||||
httpMethod: {
|
||||
key: null
|
||||
}
|
||||
}
|
||||
}),
|
||||
selection: [],
|
||||
tableData: {},
|
||||
enums: {
|
||||
LogType: {},
|
||||
HttpMethod: {}
|
||||
},
|
||||
drawer: false,
|
||||
currentRow: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
typeFilters() {
|
||||
return convertEnum(this.enums.LogType)
|
||||
},
|
||||
httpMethodFilters() {
|
||||
return convertEnum(this.enums.HttpMethod)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initEnums(['LogType', 'HttpMethod'], this.enums)
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出操作日志'
|
||||
optLogApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出操作日志'
|
||||
optLogApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
optLogApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
clear(type) {
|
||||
this.$confirm('确认要清除日志吗?', this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
optLogApi.clear({ type: type }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
|
||||
this.search()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const logIds = this.selection.map(item => item.id)
|
||||
this.delete(logIds)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(logIds) {
|
||||
optLogApi.delete({ ids: logIds })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {
|
||||
type: {
|
||||
key: null
|
||||
},
|
||||
httpMethod: {
|
||||
key: null
|
||||
}
|
||||
}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
transTime(time) {
|
||||
return `${time} ms`
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
},
|
||||
onView(row) {
|
||||
this.currentRow = row
|
||||
this.drawer = true
|
||||
},
|
||||
closeDrawer(done) {
|
||||
done()
|
||||
this.currentRow = {}
|
||||
},
|
||||
uaForamt(row) {
|
||||
const ua = readUserAgent(row.ua)
|
||||
return ua.terminal + ' | ' + ua.browser
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.drawer-item {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.box-item {
|
||||
margin-top: 15px;
|
||||
|
||||
aside {
|
||||
word-wrap: break-word;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :close-on-press-escape="true" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="systemApi" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.systemApi.serviceId')" prop="serviceId">
|
||||
<el-select
|
||||
v-model="systemApi.serviceId" :disabled="type==='view'" placeholder
|
||||
style="width:100%"
|
||||
value
|
||||
>
|
||||
<el-option v-for="item in serviceList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.systemApi.code')" prop="code">
|
||||
<el-input v-model="systemApi.code" :disabled="type==='view' || type==='edit' " />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.systemApi.name')" prop="name">
|
||||
<el-input v-model="systemApi.name" :disabled="type==='view'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.systemApi.path')" prop="path">
|
||||
<el-input v-model="systemApi.path" :disabled="type==='view'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.systemApi.status')" prop="status">
|
||||
<el-radio-group v-model="systemApi.status" border="true" size="small">
|
||||
<el-radio-button :label="true">{{ $t('common.status.valid') }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t('common.status.invalid') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<aside class="tips">禁用:提示"请求地址,禁止访问!";</aside>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.systemApi.isAuth')" prop="isAuth">
|
||||
<el-radio-group v-model="systemApi.isAuth" size="small">
|
||||
<el-radio-button :label="true">{{ $t('common.yes') }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t('common.no') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<aside class="tips">是:未认证登录,提示"认证失败,请重新登录!";否: 不需要认证登录</aside>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label="$t('table.systemApi.isOpen')" prop="isOpen">
|
||||
<el-radio-group size="small" v-model="systemApi.isOpen">
|
||||
<el-radio-button :label="true">{{ $t('common.yes') }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t('common.no') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<aside class="tips">否:提示"请求地址,拒绝访问!"</aside>
|
||||
</el-form-item>-->
|
||||
<el-form-item :label="$t('table.systemApi.describe')" prop="describe">
|
||||
<el-input v-model="systemApi.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
import systemApiApi from '@/api/SystemApi.js'
|
||||
|
||||
export default {
|
||||
name: 'SystemApiEdit',
|
||||
components: { Treeselect },
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
remoteSystemApiLoading: false,
|
||||
systemApi: this.initSystemApi(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
orgList: [],
|
||||
systemApiList: [],
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
status: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
serviceId: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 50, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
serviceList: [
|
||||
{ id: "ceres-authority-server", name: "权限服务" },
|
||||
{ id: "ceres-file-server", name: "文件服务" },
|
||||
{ id: "ceres-msgs-server", name: "消息服务" },
|
||||
{ id: "ceres-demo-server", name: "演示服务" },
|
||||
{ id: "ceres-order-server", name: "订单服务" }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return this.type === 'add' ? this.$t('common.add') : this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initSystemApi () {
|
||||
return {
|
||||
id: '',
|
||||
code: '',
|
||||
describe: '',
|
||||
requestMethod: '',
|
||||
contentType: '',
|
||||
serviceId: '',
|
||||
path: '',
|
||||
status: true,
|
||||
isOpen: true,
|
||||
isAuth: false
|
||||
}
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
loadListOptions ({ callback }) {
|
||||
callback()
|
||||
},
|
||||
setSystemApi (val, orgs) {
|
||||
const vm = this
|
||||
vm.orgList = orgs
|
||||
if (val) {
|
||||
vm.systemApi = { ...val }
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.systemApi = this.initSystemApi()
|
||||
},
|
||||
submitForm () {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const vm = this
|
||||
if (vm.type === 'add') {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const vm = this
|
||||
systemApiApi.save(this.systemApi)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
systemApiApi.update(this.systemApi)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tips {
|
||||
margin-bottom: 0;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,512 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.code" :placeholder="$t('table.systemApi.code')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.name" :placeholder="$t('table.systemApi.name')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.serviceId" :placeholder="$t('table.systemApi.serviceId')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
:start-placeholder="$t('table.createTime')"
|
||||
class="filter-item search-item date-range-item"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t('table.reset') }}</el-button>
|
||||
<el-button
|
||||
v-has-permission="['systemApi:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-has-permission="['systemApi:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="scan"
|
||||
>
|
||||
扫描接口
|
||||
</el-button>
|
||||
<el-dropdown v-has-any-permission="['systemApi:delete','systemApi:export']" class="filter-item" trigger="click">
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['systemApi:delete']" @click.native="batchDelete">
|
||||
{{ $t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['systemApi:export']" @click.native="exportExcel">
|
||||
{{ $t('table.export') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['systemApi:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @cell-click="cellClick"
|
||||
@filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column :label="$t('table.systemApi.code')" :show-overflow-tooltip="true" align="center" prop="code">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.name')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="120px"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.describe')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="120px" prop="describe"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.requestMethod')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="80px" prop="requestMethod"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.requestMethod }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.serviceId')" :show-overflow-tooltip="true" align="center"
|
||||
min-width="180px" prop="serviceId"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.serviceId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.path')" :show-overflow-tooltip="true" align="left"
|
||||
min-width="200px"
|
||||
prop="path"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.path }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.status')" :show-overflow-tooltip="true" align="center"
|
||||
prop="status"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-badge :type="scope.row.status ? 'success' :'danger'" class="status-item" is-dot />
|
||||
<span>{{ scope.row.status? $t('common.status.valid') : $t('common.status.invalid') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.isAuth')" :show-overflow-tooltip="true" align="center"
|
||||
prop="isAuth"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.isAuth ? $t('common.yes') : $t('common.no') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.isOpen')" :show-overflow-tooltip="true" align="center"
|
||||
prop="isOpen"
|
||||
width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.isOpen? $t('common.yes') : $t('common.no') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.systemApi.isPersist')" :show-overflow-tooltip="true" align="center"
|
||||
prop="isOpen" width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.isPersist? $t('common.yes') : $t('common.no') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" sortable="custom" :show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="className" width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" column-key="operation" align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
fixed="right" width="110px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-has-permission="['systemApi:update']" class="el-icon-edit table-operation" style="color: #2db7f5;"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-has-permission="['systemApi:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<i class="el-icon-view table-operation" style="color: #87d068;" @click="onView(row)"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
|
||||
<el-drawer v-model="currentRow" :before-close="closeDrawer" :visible.sync="drawer" direction="rtl">
|
||||
<div slot="title" class="clearfix">{{ currentRow.path }}</div>
|
||||
<el-scrollbar style="height: 100%;">
|
||||
<el-card class="box-card">
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.code') }}:</span>
|
||||
<aside>{{ currentRow.code }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.name') }}:</span>
|
||||
<aside style>{{ currentRow.name }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.describe') }}:</span>
|
||||
<aside style>{{ currentRow.describe }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.requestMethod') }}:</span>
|
||||
<aside style>{{ currentRow.requestMethod }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.contentType') }}:</span>
|
||||
<aside style>{{ currentRow.contentType }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.serviceId') }}:</span>
|
||||
<aside style>{{ currentRow.serviceId }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.path') }}:</span>
|
||||
<aside style>{{ currentRow.path }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.status') }}:</span>
|
||||
<aside style>{{ currentRow.status ? '是' : '否' }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.isPersist') }}:</span>
|
||||
<aside style>{{ currentRow.isPersist ? '是' : '否' }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.isAuth') }}:</span>
|
||||
<aside style>{{ currentRow.isAuth ? '是' : '否' }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.isOpen') }}:</span>
|
||||
<aside style>{{ currentRow.isOpen ? '是' : '否' }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.isPersist') }}:</span>
|
||||
<aside style>{{ currentRow.isPersist ? '是' : '否' }}</aside>
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<span class="field-label">{{ $t('table.systemApi.className') }}:</span>
|
||||
<aside style>{{ currentRow.className + '.' + currentRow.methodName }}</aside>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-scrollbar>
|
||||
</el-drawer>
|
||||
<system-api-edit
|
||||
ref="edit" :dialog-visible="dialog.isVisible" :type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<system-api-scan
|
||||
ref="scan" :dialog-visible="dialogScan.isVisible" :type="dialogScan.type"
|
||||
@close="scanClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import SystemApiEdit from './Edit'
|
||||
import SystemApiScan from './Scan'
|
||||
import systemApiApi from '@/api/SystemApi.js'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import { downloadFile, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'SystemApi',
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, SystemApiEdit, SystemApiScan },
|
||||
filters: {},
|
||||
data() {
|
||||
return {
|
||||
dialogScan: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
tableKey: 0,
|
||||
loading: false,
|
||||
queryParams: initQueryParams({
|
||||
model: {}
|
||||
}),
|
||||
selection: [],
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
drawer: false,
|
||||
currentRow: {}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出接口数据'
|
||||
systemApiApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出接口数据'
|
||||
systemApiApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
systemApiApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const isPersist = this.selection.findIndex(item => item.isPersist)
|
||||
if (isPersist > -1) {
|
||||
this.$message({
|
||||
message: "不能删除内置数据",
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const logIds = this.selection.map(item => item.id)
|
||||
this.delete(logIds)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(logIds) {
|
||||
systemApiApi.delete({ ids: logIds })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = {}
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
onView(row) {
|
||||
this.currentRow = row
|
||||
this.drawer = true
|
||||
},
|
||||
closeDrawer(done) {
|
||||
done()
|
||||
this.currentRow = {}
|
||||
},
|
||||
cellClick(row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
},
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
scanClose() {
|
||||
this.dialogScan.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = 'add'
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setSystemApi(false)
|
||||
},
|
||||
scan() {
|
||||
this.dialogScan.type = 'add'
|
||||
this.dialogScan.isVisible = true
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setSystemApi(row)
|
||||
this.dialog.type = 'edit'
|
||||
this.dialog.isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.drawer-item {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.box-item {
|
||||
margin-top: 15px;
|
||||
|
||||
aside {
|
||||
word-wrap: break-word;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :close-on-press-escape="true" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="systemApi" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
|
||||
<el-form-item :label="$t('table.systemApi.serviceId')" prop="serviceId">
|
||||
<el-select
|
||||
v-model="systemApi.serviceId" :disabled="type==='view'" placeholder
|
||||
style="width:100%"
|
||||
value
|
||||
>
|
||||
<el-option v-for="item in serviceList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import systemApiApi from '@/api/SystemApi.js'
|
||||
|
||||
export default {
|
||||
name: 'SystemApiScan',
|
||||
components: { },
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
rules: {
|
||||
},
|
||||
systemApi: {
|
||||
serviceId: 'authority'
|
||||
},
|
||||
serviceList: [
|
||||
{ id: "authority", name: "权限服务" },
|
||||
{ id: "file", name: "文件服务" },
|
||||
{ id: "msgs", name: "消息服务" },
|
||||
{ id: "demo", name: "演示服务" },
|
||||
{ id: "order", name: "订单服务" }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return '扫描Rest接口'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.serviceId = 'authority'
|
||||
},
|
||||
submitForm() {
|
||||
systemApiApi.scan(this.systemApi.serviceId).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: "扫描成功,请稍后刷新数据",
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tips {
|
||||
margin-bottom: 0;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-el-drag-dialog :close-on-click-modal="false" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
@dragDialog="handleDrag"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="attachment" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.attachment.bizId')" prop="bizId">
|
||||
<el-input v-model="attachment.bizId" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('table.attachment.bizType')" prop="bizType">
|
||||
<el-input v-model="attachment.bizType" />
|
||||
</el-form-item>
|
||||
<el-form-item label="文件" prop="fileLength">
|
||||
<fileUpload
|
||||
ref="fileRef" :accept-size="2*1024*1024" :auto-upload="false"
|
||||
:limit="5"
|
||||
@fileLengthVaild="fileLengthVaild" @setId="setIdAndSubmit"
|
||||
>
|
||||
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
|
||||
<div slot="tip" class="el-upload__tip">文件不超过2MB</div>
|
||||
</fileUpload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button :disabled="disabled" plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import fileUpload from "@/components/ceres/fileUpload"
|
||||
|
||||
export default {
|
||||
name: 'AttachmentEdit',
|
||||
directives: { elDragDialog, fileUpload },
|
||||
components: { fileUpload },
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
accept: "image/jpeg, image/gif, image/png",
|
||||
attachment: this.initAttachment(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
fileLength: 0,
|
||||
disabled: false,
|
||||
rules: {
|
||||
bizType: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 0, max: 255, message: this.$t('rules.range0to255'), trigger: 'blur' }
|
||||
],
|
||||
bizId: { min: 0, max: 255, message: this.$t('rules.range0to255'), trigger: 'blur' },
|
||||
fileLength: { required: true, trigger: "change",
|
||||
validator: (rule, value, callback) => {
|
||||
const vm = this
|
||||
if (vm.fileLength === 0) {
|
||||
callback(new Error("请上传文件"))
|
||||
} else if (vm.fileLength > 5) {
|
||||
callback(new Error("一次性只能上传5个文件"))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return this.$t('common.upload')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initAttachment () {
|
||||
return {
|
||||
id: '',
|
||||
bizId: '',
|
||||
bizType: '',
|
||||
file: null,
|
||||
isSingle: false
|
||||
}
|
||||
},
|
||||
handleDrag () {
|
||||
console.log(`我被拖动了`)
|
||||
},
|
||||
// 附件长度校验
|
||||
fileLengthVaild (data) {
|
||||
const vm = this
|
||||
vm.fileLength = data || 0
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
setAttachment (val) {
|
||||
const vm = this
|
||||
if (val) {
|
||||
vm.attachment = { ...val }
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.attachment = this.initAttachment()
|
||||
this.$refs.fileRef.init({
|
||||
id: "",
|
||||
bizId: "",
|
||||
bizType: ""
|
||||
})
|
||||
},
|
||||
submitForm () {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const vm = this
|
||||
vm.disabled = true
|
||||
vm.$refs.fileRef.submitFile(this.attachment.id, this.attachment.bizId, this.attachment.bizType)
|
||||
},
|
||||
setIdAndSubmit (isUploadCompleted) {
|
||||
const vm = this
|
||||
if (isUploadCompleted) {
|
||||
vm.disabled = false
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,435 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.submittedFileName"
|
||||
:placeholder="$t('table.attachment.submittedFileName')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">
|
||||
{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-has-permission="['file:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="upload"
|
||||
>
|
||||
{{ $t("table.upload") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['file:delete', 'file:download']"
|
||||
class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-has-permission="['file:delete']"
|
||||
@click.native="batchDelete"
|
||||
>{{ $t("table.delete") }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-has-permission="['file:download']"
|
||||
@click.native="batchDownload"
|
||||
>{{ $t("table.download") }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.attachment.submittedFileName')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="left"
|
||||
prop="submittedFileName"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div class="hover-effect" @click="onView(scope.row)">
|
||||
<i :class="scope.row.icon" class="button-list"></i>
|
||||
<span>{{ scope.row.submittedFileName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.attachment.dataType')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="dataType"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.dataType.desc }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.attachment.bizType')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
width="120px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.bizType }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.attachment.bizId')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
width="180px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.bizId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.attachment.size')"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
width="120px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ formatSize(scope.row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')"
|
||||
align="center" column-key="operation"
|
||||
class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-hasPermission="['file:download']"
|
||||
class="el-icon-download table-operation"
|
||||
style="color: #f50;"
|
||||
@click="singleDownload(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['file:delete']"
|
||||
class="el-icon-delete table-operation"
|
||||
style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link
|
||||
v-has-no-permission="['file:update', 'file:delete']"
|
||||
class="no-perm"
|
||||
>{{ $t("tips.noPermission") }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<attachment-edit
|
||||
ref="edit"
|
||||
:dialog-visible="dialog.isVisible"
|
||||
:type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<el-dialog :visible.sync="dialogVisible">
|
||||
<img
|
||||
v-if="dialogImageUrl"
|
||||
:key="dialogImageUrl"
|
||||
:src="dialogImageUrl"
|
||||
alt="图片飞到火星了"
|
||||
height="500px"
|
||||
width="100%"
|
||||
@error="errorImage()"
|
||||
/>
|
||||
<span v-else>图片飞到火星了~</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from "@/components/Pagination"
|
||||
import AttachmentEdit from "./Edit"
|
||||
import attachmentApi from "@/api/Attachment.js"
|
||||
import { renderSize } from "@/utils/utils"
|
||||
import { onlinePreview } from "@/settings"
|
||||
import { downloadFile, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "AttachmentManage",
|
||||
components: { Pagination, AttachmentEdit },
|
||||
filters: {},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
dialogImageUrl: "",
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: "add"
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
records: [],
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
errorImage() {
|
||||
const img = event.srcElement
|
||||
img.src = require("@/assets/404_images/404_image.jpeg")
|
||||
img.onerror = null // 防止闪图
|
||||
},
|
||||
formatSize(row) {
|
||||
return renderSize(row.size)
|
||||
},
|
||||
filterStatus(value, row) {
|
||||
return row.status === value
|
||||
},
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
singleDownload(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDownload()
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDownload() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm("确认下载吗?", this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.download(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
download(ids) {
|
||||
attachmentApi.download({ ids: ids }).then(response => {
|
||||
downloadFile(response)
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
delete(ids) {
|
||||
attachmentApi.delete({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
if (row.url) {
|
||||
window.open(onlinePreview + encodeURIComponent(row.url))
|
||||
}
|
||||
},
|
||||
upload() {
|
||||
this.dialog.type = "upload"
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setAttachment(false)
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setAttachment(row)
|
||||
this.dialog.type = "edit"
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
attachmentApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.file-breadcrumb {
|
||||
margin: 10px 0px 20px;
|
||||
}
|
||||
.page {
|
||||
text-align: center;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.button-list {
|
||||
margin-right: 10px;
|
||||
font-size: 20px !important;
|
||||
color: #22a2ed;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.title {
|
||||
color: #777;
|
||||
font-size: 2em;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
div{
|
||||
&.hover-effect {
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.025);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,524 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.title"
|
||||
:placeholder="$t('table.msgs.title')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.content"
|
||||
:placeholder="$t('table.msgs.content')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">
|
||||
{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<router-link :to="{ path: '/msgs/sendMsgs', query: { type: 'add' } }">
|
||||
<el-button v-has-permission="['msgs:add']" class="filter-item" plain type="danger">
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
</router-link>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['msgs:delete', 'msgs:export']"
|
||||
class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<!-- <router-link :to="{ path: '/msgs/sendMsgs', query: { type: 'add' } }">-->
|
||||
<!-- <el-dropdown-item v-has-permission="['msgs:add']">-->
|
||||
<!-- {{ $t("table.add") }}-->
|
||||
<!-- </el-dropdown-item>-->
|
||||
<!-- </router-link>-->
|
||||
<el-dropdown-item v-has-permission="['msgs:delete']" @click.native="batchDelete">
|
||||
{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['msgs:mark']" @click.native="batchMark">
|
||||
标记已读
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['msgs:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['msgs:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['msgs:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.msgs.title')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="templateId"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.msgs.content')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="receiver"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.content }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.msgs.author')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="bizTypeFilters"
|
||||
:label="$t('table.msgs.bizType')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
column-key="bizType.code"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.bizType ? scope.row.bizType.desc : "" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="msgsCenterTypeFilters"
|
||||
:label="$t('table.msgs.msgsCenterType')"
|
||||
:show-overflow-tooltip="true"
|
||||
class-name="status-col"
|
||||
column-key="msgsCenterType.code"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{
|
||||
scope.row.msgsCenterType
|
||||
? scope.row.msgsCenterType.desc
|
||||
: scope.row.msgsCenterType
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="[
|
||||
{ text: '已读', value: 'true' },
|
||||
{ text: '未读', value: 'false' }
|
||||
]"
|
||||
:label="$t('table.msgs.isRead')"
|
||||
align="center"
|
||||
column-key="isRead"
|
||||
prop="isRead"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-tag slot :type="scope.row.isRead ? 'success' : 'danger'">{{
|
||||
scope.row.isRead ? "已读" : "未读"
|
||||
}}</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
column-key="operation"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-hasPermission="['msgs:view']"
|
||||
class="el-icon-view table-operation"
|
||||
style="color: #2db7f5;"
|
||||
@click="view(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['msgs:delete']"
|
||||
class="el-icon-delete table-operation"
|
||||
style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link
|
||||
v-has-no-permission="['msgs:view', 'msgs:delete']"
|
||||
class="no-perm"
|
||||
>{{ $t("tips.noPermission") }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from "@/components/Pagination"
|
||||
import msgsApi from "@/api/Msgs.js"
|
||||
import { convertEnum } from "@/utils/utils"
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import { downloadFile, initMsgsEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "MsgsList",
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, FileImport },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
WAITING: "danger",
|
||||
SUCCESS: "success",
|
||||
FAIL: "error"
|
||||
}
|
||||
return map[status] || "success"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: "add"
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/msgs/msgsCenterInfo/import`
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {
|
||||
msgsCenterType: { code: null },
|
||||
bizType: { code: null }
|
||||
}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: {
|
||||
MsgsCenterType: {},
|
||||
MsgsBizType: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
msgsCenterTypeFilters() {
|
||||
return convertEnum(this.enums.MsgsCenterType)
|
||||
},
|
||||
bizTypeFilters() {
|
||||
return convertEnum(this.enums.MsgsBizType)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route'(to) {
|
||||
if (to.path === '/msgs/myMsgs') {
|
||||
this.fetch()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initMsgsEnums(['MsgsCenterType', 'MsgsBizType'], this.enums)
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
filterStatus(value, row) {
|
||||
return row.status === value
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {
|
||||
msgsCenterType: { code: null },
|
||||
bizType: { code: null }
|
||||
}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出消息数据'
|
||||
msgsApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出消息数据'
|
||||
msgsApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
|
||||
delete(ids) {
|
||||
msgsApi.delete({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
batchMark() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm("确认全部标记为已读吗?", this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.mark(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
mark(ids, callback) {
|
||||
msgsApi.mark({ msgCenterIds: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (typeof callback === "function") {
|
||||
callback(ids)
|
||||
}
|
||||
})
|
||||
},
|
||||
view(row) {
|
||||
if (row.isRead) {
|
||||
this.$router.push({
|
||||
path: "/msgs/sendMsgs",
|
||||
query: {
|
||||
id: row.id,
|
||||
type: "view"
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.mark([row.id], ids => {
|
||||
this.$router.push({
|
||||
path: "/msgs/sendMsgs",
|
||||
query: {
|
||||
id: row.id,
|
||||
type: "view"
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
edit(row) {
|
||||
this.$router.push({
|
||||
path: "/msgs/sendMsgs",
|
||||
query: {
|
||||
id: row.id,
|
||||
type: "edit"
|
||||
}
|
||||
})
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
msgsApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick(row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,412 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
ref="form" :model="msgsCenterInfo" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px" status-icon
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.title')" prop="msgsCenterInfoDTO.title">
|
||||
<el-input v-model="msgsCenterInfo.msgsCenterInfoDTO.title" :disabled="type==='view'" :maxlength="255" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.bizType')" prop="msgsCenterInfoDTO.bizType">
|
||||
<el-select
|
||||
v-model="msgsCenterInfo.msgsCenterInfoDTO.bizType.code" :disabled="type==='view'" clearable
|
||||
placeholder
|
||||
style="width:100%" value
|
||||
>
|
||||
<el-option v-for="(item, key, index) in enums.MsgsBizType" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.bizId')" prop="msgsCenterInfoDTO.bizId">
|
||||
<el-input v-model="msgsCenterInfo.msgsCenterInfoDTO.bizId" :disabled="type==='view'" :maxlength="255" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.msgsCenterType')" prop="msgsCenterInfoDTO.msgsCenterType">
|
||||
<el-select
|
||||
v-model="msgsCenterInfo.msgsCenterInfoDTO.msgsCenterType.code" :disabled="type==='view'" placeholder
|
||||
style="width:100%"
|
||||
value @change="msgsCenterTypeChange"
|
||||
>
|
||||
<el-option v-for="(item, key, index) in enums.MsgsCenterType" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item v-show="type!=='view'" label="接收类型" prop="msgsCenterInfoDTO.receiveType">
|
||||
<el-radio-group v-model="msgsCenterInfo.receiveType" :disabled="type==='view' || disabledReceiveType">
|
||||
<el-radio-button label="user">用户</el-radio-button>
|
||||
<el-radio-button label="role">角色</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item v-if="msgsCenterInfo.receiveType==='user'" v-show="type!=='view'" label="接收用户" prop="userIdList">
|
||||
<el-select
|
||||
v-model="msgsCenterInfo.userIdList" :disabled="type==='view' || disabledReceiveType" collapse-tags
|
||||
multiple
|
||||
placeholder style="width:100%" value
|
||||
@change="userSelect"
|
||||
>
|
||||
<el-option v-for="item in allUserList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-else v-show="type!=='view'" label="接收角色" prop="roleCodeList">
|
||||
<el-select
|
||||
v-model="msgsCenterInfo.roleCodeList" :disabled="type==='view' || disabledReceiveType" collapse-tags
|
||||
multiple
|
||||
placeholder style="width:100%" value
|
||||
@change="roleSelect"
|
||||
>
|
||||
<el-option v-for="item in allRoleList" :key="item.code" :label="item.name" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.author')" prop="msgsCenterInfoDTO.author">
|
||||
<el-input v-model="msgsCenterInfo.msgsCenterInfoDTO.author" :disabled="type==='view'" :maxlength="255" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.handlerUrl')" prop="msgsCenterInfoDTO.handlerUrl">
|
||||
<el-input v-model="msgsCenterInfo.msgsCenterInfoDTO.handlerUrl" :disabled="type==='view'" :maxlength="255" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('table.msgs.isSingleHandle')" prop="msgsCenterInfoDTO.isSingleHandle">
|
||||
<el-radio-group v-model="msgsCenterInfo.msgsCenterInfoDTO.isSingleHandle" :disabled="type==='view'">
|
||||
<el-radio-button :label="true">{{ $t('common.yes') }}</el-radio-button>
|
||||
<el-radio-button :label="false">{{ $t('common.no') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item prop="msgsCenterInfoDTO.content" style="margin-bottom: 30px;">
|
||||
<Tinymce ref="content" v-model="msgsCenterInfo.msgsCenterInfoDTO.content" :height="400" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="dialog-footer">
|
||||
<el-button
|
||||
v-show="type!=='view'" :disabled="disabled" plain
|
||||
type="primary"
|
||||
@click="submitForm(false)"
|
||||
>发送</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import msgsApi from '@/api/Msgs.js'
|
||||
import roleApi from '@/api/Role.js'
|
||||
import userApi from '@/api/User.js'
|
||||
import Tinymce from '@/components/Tinymce'
|
||||
import { initMsgsEnums } from '@/utils/commons.js'
|
||||
|
||||
export default {
|
||||
name: 'MsgsEdit',
|
||||
components: { Tinymce },
|
||||
filters: {
|
||||
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
allUserList: [],
|
||||
allRoleList: [],
|
||||
oldChooseUserIdList: [[]],
|
||||
oldChooseRoleIdList: [[]],
|
||||
dialog: {
|
||||
isVisible: false
|
||||
},
|
||||
type: 'add',
|
||||
msgsCenterInfo: this.initMsgsCenterInfo(),
|
||||
disabled: false,
|
||||
disabledReceiveType: false,
|
||||
enums: {
|
||||
MsgsBizType: {},
|
||||
MsgsCenterType: {}
|
||||
},
|
||||
rules: {
|
||||
"msgsCenterInfoDTO.title": [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: "长度在 1 到 255 个字符", trigger: 'blur' }
|
||||
],
|
||||
"msgsCenterInfoDTO.content": [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 65535, message: "长度在 1 到 65535 个字符", trigger: 'blur' }
|
||||
],
|
||||
"msgsCenterInfoDTO.msgsCenterType": { required: true, message: this.$t('rules.require'), trigger: 'change' },
|
||||
"roleCodeList": {
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.msgsCenterInfo.receiveType === 'role' && this.msgsCenterInfo.msgsCenterInfoDTO.msgsCenterType.code !== 'PUBLICITY' && this.msgsCenterInfo.roleCodeList.length <= 0) {
|
||||
callback('请选择角色')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'blur'
|
||||
},
|
||||
"userIdList": {
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.msgsCenterInfo.receiveType === 'user' && this.msgsCenterInfo.msgsCenterInfoDTO.msgsCenterType.code !== 'PUBLICITY' && this.msgsCenterInfo.userIdList.length <= 0) {
|
||||
callback('请选择用户')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'blur'
|
||||
},
|
||||
"msgsCenterInfoDTO.handlerUrl": { min: 1, max: 255, message: "长度在 1 到 255 个字符", trigger: 'blur' }
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
$route () {
|
||||
if (this.$route.path === '/msgs/sendMsgs') {
|
||||
this.loadMsgs()
|
||||
this.loadUserList()
|
||||
this.loadRoleList()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.loadMsgs()
|
||||
this.loadUserList()
|
||||
this.loadRoleList()
|
||||
initMsgsEnums(['MsgsCenterType', 'MsgsBizType'], this.enums)
|
||||
},
|
||||
methods: {
|
||||
initMsgsCenterInfo () {
|
||||
return {
|
||||
userIdList: [],
|
||||
roleCodeList: [],
|
||||
receiveType: 'user',
|
||||
msgsCenterInfoDTO: {
|
||||
id: '',
|
||||
bizId: '',
|
||||
bizType: {
|
||||
code: ''
|
||||
},
|
||||
msgsCenterType: {
|
||||
code: ''
|
||||
},
|
||||
title: '',
|
||||
content: '',
|
||||
author: '',
|
||||
handlerUrl: '',
|
||||
handlerParams: '',
|
||||
isSingleHandle: true
|
||||
}
|
||||
}
|
||||
},
|
||||
loadMsgs () {
|
||||
const type = this.$route.query.type
|
||||
const id = this.$route.query.id
|
||||
this.type = type
|
||||
if (type === 'view') {
|
||||
msgsApi.get(id)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.msgsCenterInfo.msgsCenterInfoDTO = res.data
|
||||
if (this.msgsCenterInfo.msgsCenterInfoDTO.bizType === null) {
|
||||
this.msgsCenterInfo.msgsCenterInfoDTO.bizType = { code: '' }
|
||||
}
|
||||
if (this.msgsCenterInfo.msgsCenterInfoDTO.msgsCenterType === null) {
|
||||
this.msgsCenterInfo.msgsCenterInfoDTO.msgsCenterType = { code: '' }
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
loadUserList () {
|
||||
userApi.page({ current: 1, size: 10000, model: { status: true }})
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
if (res.data.records.length > 0) {
|
||||
this.allUserList = [...[{ id: '-1', name: '全选' }], ...res.data.records]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
loadRoleList () {
|
||||
roleApi.page({ current: 1, size: 10000, model: { status: true }})
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
if (res.data.records.length > 0) {
|
||||
this.allRoleList = [...[{ code: '-1', name: '全选' }], ...res.data.records]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
msgsCenterTypeChange (select) {
|
||||
if (select === 'PUBLICITY') {
|
||||
this.disabledReceiveType = true
|
||||
} else {
|
||||
this.disabledReceiveType = false
|
||||
}
|
||||
},
|
||||
userSelect (val) {
|
||||
// 保留所有值
|
||||
const allValues = this.allUserList.map(item => item.id)
|
||||
|
||||
// 用来储存上一次的值,可以进行对比
|
||||
const oldVal = this.oldChooseUserIdList.length === 1 ? [] : this.oldChooseUserIdList[1]
|
||||
|
||||
// 若是全部选择
|
||||
if (val.includes('-1')) {
|
||||
this.msgsCenterInfo.userIdList = allValues
|
||||
}
|
||||
|
||||
// 取消全部选中 上次有 当前没有 表示取消全选
|
||||
if (oldVal.includes('-1') && !val.includes('-1')) {
|
||||
this.msgsCenterInfo.userIdList = []
|
||||
}
|
||||
|
||||
// 点击非全部选中 需要排除全部选中 以及 当前点击的选项
|
||||
// 新老数据都有全部选中
|
||||
if (oldVal.includes('-1') && val.includes('-1')) {
|
||||
const index = val.indexOf('-1')
|
||||
val.splice(index, 1) // 排除全选选项
|
||||
this.msgsCenterInfo.userIdList = val
|
||||
}
|
||||
|
||||
// 全选未选 但是其他选项全部选上 则全选选上 上次和当前 都没有全选
|
||||
if (!oldVal.includes('-1') && !val.includes('-1')) {
|
||||
if (val.length === allValues.length - 1) {
|
||||
this.msgsCenterInfo.userIdList = ['-1'].concat(val)
|
||||
}
|
||||
}
|
||||
|
||||
// 储存当前最后的结果 作为下次的老数据
|
||||
this.oldChooseUserIdList[1] = this.msgsCenterInfo.userIdList
|
||||
},
|
||||
roleSelect (val) {
|
||||
// 保留所有值
|
||||
const allValues = this.allRoleList.map(item => item.code)
|
||||
|
||||
// 用来储存上一次的值,可以进行对比
|
||||
const oldVal = this.oldChooseRoleIdList.length === 1 ? [] : this.oldChooseRoleIdList[1]
|
||||
|
||||
// 若是全部选择
|
||||
if (val.includes('-1')) {
|
||||
this.msgsCenterInfo.roleCodeList = allValues
|
||||
}
|
||||
|
||||
// 取消全部选中 上次有 当前没有 表示取消全选
|
||||
if (oldVal.includes('-1') && !val.includes('-1')) {
|
||||
this.msgsCenterInfo.roleCodeList = []
|
||||
}
|
||||
|
||||
// 点击非全部选中 需要排除全部选中 以及 当前点击的选项
|
||||
// 新老数据都有全部选中
|
||||
if (oldVal.includes('-1') && val.includes('-1')) {
|
||||
const index = val.indexOf('-1')
|
||||
val.splice(index, 1) // 排除全选选项
|
||||
this.msgsCenterInfo.roleCodeList = val
|
||||
}
|
||||
|
||||
// 全选未选 但是其他选项全部选上 则全选选上 上次和当前 都没有全选
|
||||
if (!oldVal.includes('-1') && !val.includes('-1')) {
|
||||
if (val.length === allValues.length - 1) {
|
||||
this.msgsCenterInfo.roleCodeList = ['-1'].concat(val)
|
||||
}
|
||||
}
|
||||
|
||||
// 储存当前最后的结果 作为下次的老数据
|
||||
this.oldChooseRoleIdList[1] = this.msgsCenterInfo.roleCodeList
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.msgsCenterInfo = this.initMsgsCenterInfo()
|
||||
this.disabledReceiveType = false
|
||||
|
||||
// 这里报错
|
||||
// this.$nextTick(() =>
|
||||
// this.$refs.content.setContent('')
|
||||
// )
|
||||
|
||||
// 设置设置的时间短了 也报错
|
||||
setTimeout(() => {
|
||||
this.$refs.content.setContent('')
|
||||
}, 1000)
|
||||
},
|
||||
submitForm (draft) {
|
||||
const vm = this
|
||||
console.log(vm.msgsCenterInfo)
|
||||
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit(draft)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit (draft) {
|
||||
const vm = this
|
||||
if (vm.type === 'edit') {
|
||||
vm.update()
|
||||
} else {
|
||||
vm.save()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const vm = this
|
||||
vm.disabled = true
|
||||
msgsApi.save(vm.msgsCenterInfo)
|
||||
.then((response) => {
|
||||
vm.disabled = false
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.reset()
|
||||
vm.$router.push('/msgs/myMsgs')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
const vm = this
|
||||
vm.disabled = true
|
||||
msgsApi.update(vm.msgs)
|
||||
.then((response) => {
|
||||
vm.disabled = false
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.reset()
|
||||
vm.$router.push('/msgs/myMsgs')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,507 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
ref="form" :model="smsTask" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px" status-icon
|
||||
>
|
||||
<el-row>
|
||||
<el-col :sm="12" :xs="24" style="margin-top: 10px;">
|
||||
<el-form-item :label="$t('table.smsTask.templateId')" prop="templateId">
|
||||
<el-select
|
||||
v-model="smsTask.templateId" :disabled="type==='view'" :multiple="false"
|
||||
filterable
|
||||
placeholder="请输入关键词" style="width:300px;" @change="changeTemplate"
|
||||
>
|
||||
<el-option v-for="item in smsTemplateList" :key="item.id" :label="item.name + '('+item.customCode+')'" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24" style="margin-top: 10px;">
|
||||
<el-form-item v-show="type==='view'" :label="$t('table.smsTask.status')" prop="status">
|
||||
<el-tag :disabled="type==='view'" :type="smsTask.status | statusFilter">{{ smsTask.status.desc }}</el-tag>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('table.smsTask.receiver')" prop="receiver">
|
||||
<el-tag
|
||||
v-for="tag in receiverList" :key="tag" :closable="type!=='view'"
|
||||
:disable-transitions="false"
|
||||
@close="handleClose(tag)"
|
||||
>{{ tag }}</el-tag>
|
||||
<el-input
|
||||
v-if="receiverVisible" ref="saveTagInput" v-model="receiver"
|
||||
:disabled="type==='view'"
|
||||
class="input-new-tag" @blur="handleInputConfirm" @keyup.enter.native="handleInputConfirm"
|
||||
/>
|
||||
<el-button v-else :disabled="type==='view'" class="button-new-tag" @click="showInput">添加</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTask.topic')" prop="topic">
|
||||
<el-input v-model="smsTask.topic" :disabled="type==='view'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTask.content')" prop="content2">
|
||||
<el-row class="message">
|
||||
<el-col :sm="12" :xs="24" style="margin-top: 10px;">
|
||||
<el-form-item v-for="(item, key, index) in smsTask.templateParam" :key="index" :label="key" prop="content">
|
||||
<el-input :disabled="type==='view'" :value="item" maxlength="255" @input="(value)=>{templateCode(value,key,index)}" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24" style="margin-top: 10px;">
|
||||
<el-form-item label="预览:">
|
||||
<div class="article" v-html="smsTask.content"></div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :sm="12" :xs="24" style="margin-top: 10px;">
|
||||
<el-form-item label="定时发送" prop="sendTime">
|
||||
<el-radio-group v-model="timing" :disabled="type==='view'" size="medium">
|
||||
<el-radio-button :label="false">否</el-radio-button>
|
||||
<el-radio-button :label="true">是</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-date-picker
|
||||
v-show="timing"
|
||||
v-model="smsTask.sendTime"
|
||||
:disabled="type==='view'"
|
||||
:picker-options="pickerOptions"
|
||||
align="right"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="选择发送时间"
|
||||
style="margin-left:20px"
|
||||
type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24" style="margin-top: 10px;">
|
||||
<el-form-item v-show="type==='view'" label="是否草稿" prop="draft">
|
||||
<el-radio-group v-model="smsTask.draft" :disabled="type==='view'" size="medium">
|
||||
<el-radio-button :label="false">否</el-radio-button>
|
||||
<el-radio-button :label="true">是</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="dialog-footer">
|
||||
<el-button
|
||||
v-show="type!=='view'" :disabled="disabled" plain
|
||||
type="primary"
|
||||
@click="submitForm(false)"
|
||||
>立即发送</el-button>
|
||||
<el-button
|
||||
v-show="type!=='view'" :disabled="disabled" plain
|
||||
type="warning"
|
||||
@click="submitForm(true)"
|
||||
>存草稿</el-button>
|
||||
</div>
|
||||
<aside v-show="type!=='view'" class="tips">
|
||||
模板提示:
|
||||
<p>1.长度不超过500字,单条短信超过70字后,按67字/条分多条计费;</p>
|
||||
<p>2.短信模板内容不能包含【】符号。</p>
|
||||
</aside>
|
||||
<div v-show="type==='view'">
|
||||
<send-status-index ref="statusList" :dialog-visible="dialog.isVisible" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import smsTemplateApi from '@/api/SmsTemplate.js'
|
||||
import smsTaskApi from '@/api/SmsTask.js'
|
||||
import { validMobile } from '@/utils/my-validate'
|
||||
import SendStatusIndex from './SendStatusIndex'
|
||||
|
||||
export default {
|
||||
name: 'SmsTaskEdit',
|
||||
components: { SendStatusIndex },
|
||||
filters: {
|
||||
statusFilter (status) {
|
||||
const map = {
|
||||
WAITING: 'danger',
|
||||
SUCCESS: 'success',
|
||||
FAIL: 'error'
|
||||
}
|
||||
return map[status] || 'success'
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false
|
||||
},
|
||||
type: 'add',
|
||||
smsTask: this.initSmsTask(),
|
||||
smsTemplateList: [],
|
||||
receiverList: [],
|
||||
receiverVisible: false,
|
||||
receiver: '',
|
||||
timing: false,
|
||||
disabled: false,
|
||||
smsTemplate: '',
|
||||
content: '',
|
||||
rules: {
|
||||
topic: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range4to10'), trigger: 'blur' }
|
||||
],
|
||||
templateId: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
sendTime: {
|
||||
validator: (rule, value, callback) => {
|
||||
const vm = this
|
||||
if (vm.timing) {
|
||||
if (vm.smsTask.sendTime) {
|
||||
callback()
|
||||
} else {
|
||||
callback('请选择发送日期')
|
||||
}
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'change'
|
||||
}
|
||||
},
|
||||
pickerOptions: {
|
||||
shortcuts: [{
|
||||
text: '一小时后',
|
||||
onClick (picker) {
|
||||
const date = new Date()
|
||||
date.setTime(date.getTime() + 3600 * 1000 * 1)
|
||||
picker.$emit('pick', date)
|
||||
}
|
||||
}, {
|
||||
text: '明天',
|
||||
onClick (picker) {
|
||||
const date = new Date()
|
||||
date.setTime(date.getTime() + 3600 * 1000 * 24)
|
||||
picker.$emit('pick', date)
|
||||
}
|
||||
}, {
|
||||
text: '一周后',
|
||||
onClick (picker) {
|
||||
const date = new Date()
|
||||
date.setTime(date.getTime() + 3600 * 1000 * 24 * 7)
|
||||
picker.$emit('pick', date)
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
$route () {
|
||||
if (this.$route.path === '/sms/manage/edit') {
|
||||
this.initSmsTemplateList()
|
||||
this.loadSendStatus()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 在vue的mount阶段执行的函数都是顺序执行,不会阻塞的,所以如果希望mount阶段的函数也是阻塞的,需要额外写一个async函数,然后把需要同步执行的函数写到里面,然后在mount阶段调用这个额外写的函数
|
||||
this.initSmsTemplateList()
|
||||
this.loadSendStatus()
|
||||
},
|
||||
methods: {
|
||||
loadSendStatus () {
|
||||
const type = this.$route.query.type
|
||||
const id = this.$route.query.id
|
||||
if (type === 'view') {
|
||||
this.$refs.statusList.setTaskId(id)
|
||||
}
|
||||
},
|
||||
async loadSmsTask () {
|
||||
const type = this.$route.query.type
|
||||
const id = this.$route.query.id
|
||||
this.type = type
|
||||
if (type) { // 切换到别的页面时,无需重置表单
|
||||
// this.smsTask = this.initSmsTask()
|
||||
this.reset()
|
||||
}
|
||||
if (type === 'view') {
|
||||
this.disabled = true
|
||||
} else {
|
||||
this.disabled = false
|
||||
}
|
||||
|
||||
if (id) {
|
||||
await smsTaskApi.get(id)
|
||||
.then(response => {
|
||||
const res = response.data
|
||||
this.smsTask = { ...this.smsTask, ...res.data }
|
||||
if (type !== 'edit') {
|
||||
this.smsTask.id = ''
|
||||
}
|
||||
this.changeTemplate(this.smsTask.templateId)
|
||||
this.receiverList = this.smsTask.receiver.split(",")
|
||||
|
||||
if (this.smsTask.templateParams) {
|
||||
this.smsTask.templateParam = JSON.parse(this.smsTask.templateParams)
|
||||
}
|
||||
this.smsTask.content = res.data.content
|
||||
console.log('查询')
|
||||
if (this.smsTask.sendTime) {
|
||||
this.timing = true
|
||||
} else {
|
||||
this.timing = false
|
||||
}
|
||||
|
||||
this.smsTemplate = this.smsTemplateList.find(item => item.id === this.smsTask.templateId)
|
||||
})
|
||||
}
|
||||
},
|
||||
changeTemplate (id) {
|
||||
const vm = this
|
||||
// vm.preSearch()
|
||||
if (id) {
|
||||
// 遍历模板添加文本框
|
||||
for (const item of vm.smsTemplateList) {
|
||||
if (item.id === id) {
|
||||
let templateParam = {}
|
||||
if (typeof (item.templateParams) === 'string') {
|
||||
templateParam = JSON.parse(item.templateParams)
|
||||
} else {
|
||||
templateParam = item.templateParams
|
||||
}
|
||||
|
||||
for (const prop in templateParam) {
|
||||
templateParam[prop] = ''
|
||||
}
|
||||
vm.smsTemplate = item
|
||||
if (vm.type !== 'view') {
|
||||
console.log('赋值')
|
||||
vm.smsTask.templateParam = templateParam
|
||||
// vm.smsTask.content = item.content
|
||||
this.content = item.content
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
vm.changeContent()
|
||||
}
|
||||
},
|
||||
// 模板文本框输入内容
|
||||
templateCode (val, key) {
|
||||
const vm = this
|
||||
vm.smsTask.templateParam[key] = val
|
||||
vm.changeContent()
|
||||
},
|
||||
// 短信内容处理
|
||||
changeContent () {
|
||||
const vm = this
|
||||
if (!vm.smsTemplate) {
|
||||
return
|
||||
}
|
||||
const type = vm.smsTemplate.providerType.code
|
||||
let content = vm.smsTemplate.content
|
||||
|
||||
for (const key in vm.smsTask.templateParam) {
|
||||
let strs = ''
|
||||
if (type == "TENCENT") {
|
||||
strs = '{' + key + '}'
|
||||
} else {
|
||||
strs = '${' + key + '}'
|
||||
}
|
||||
if (vm.smsTask.templateParam[key]) {
|
||||
content = content.replace(strs, vm.smsTask.templateParam[key])
|
||||
}
|
||||
}
|
||||
if (vm.type !== 'view') {
|
||||
console.log('赋值')
|
||||
vm.smsTask.content = content
|
||||
}
|
||||
},
|
||||
async initSmsTemplateList () {
|
||||
await smsTemplateApi.page({ current: 1, size: 10000, model: {}})
|
||||
.then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.smsTemplateList = res.data.records
|
||||
}
|
||||
})
|
||||
await this.loadSmsTask() // 顺序不能变
|
||||
},
|
||||
initSmsTask () {
|
||||
return {
|
||||
templateId: '',
|
||||
receiver: '',
|
||||
topic: '',
|
||||
templateParam: {},
|
||||
sendTime: null,
|
||||
content: '',
|
||||
draft: false,
|
||||
status: {
|
||||
code: '',
|
||||
desc: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.smsTask = this.initSmsTask()
|
||||
this.receiverList = []
|
||||
},
|
||||
submitForm (draft) {
|
||||
const vm = this
|
||||
if (vm.smsTask.templateParam && Object.keys(vm.smsTask.templateParam).length > 0) {
|
||||
let flag = false
|
||||
for (const key in vm.smsTask.templateParam) {
|
||||
if (!vm.smsTask.templateParam[key]) {
|
||||
flag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
vm.$message({
|
||||
message: '发送内容不能为空',
|
||||
type: 'error'
|
||||
})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
vm.$message({
|
||||
message: '发送内容不能为空',
|
||||
type: 'error'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit(draft)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit (draft) {
|
||||
const vm = this
|
||||
vm.smsTask.draft = draft
|
||||
vm.smsTask.receiver = vm.receiverList.join(',')
|
||||
if (!vm.timing) {
|
||||
vm.smsTask.sendTime = null
|
||||
}
|
||||
if (vm.type === 'edit') {
|
||||
vm.update()
|
||||
} else {
|
||||
vm.save()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const vm = this
|
||||
vm.disabled = true
|
||||
smsTaskApi.save(vm.smsTask)
|
||||
.then((response) => {
|
||||
vm.disabled = false
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.reset()
|
||||
vm.$router.push('/sms/manage')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
const vm = this
|
||||
vm.disabled = true
|
||||
smsTaskApi.update(vm.smsTask)
|
||||
.then((response) => {
|
||||
vm.disabled = false
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.reset()
|
||||
vm.$router.push('/sms/manage')
|
||||
}
|
||||
})
|
||||
},
|
||||
handleClose (tag) {
|
||||
this.receiverList.splice(this.receiverList.indexOf(tag), 1)
|
||||
},
|
||||
showInput () {
|
||||
this.receiverVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.saveTagInput.$refs.input.focus()
|
||||
})
|
||||
},
|
||||
handleInputConfirm () {
|
||||
const vm = this
|
||||
// 正则校验
|
||||
const inputValue = vm.receiver
|
||||
if (inputValue) {
|
||||
if (!validMobile(inputValue)) {
|
||||
this.$message({
|
||||
message: '该手机号不合法',
|
||||
type: 'error'
|
||||
})
|
||||
vm.$refs.saveTagInput.focus()
|
||||
return
|
||||
}
|
||||
|
||||
if (this.receiverList.indexOf(inputValue) === -1) {
|
||||
vm.receiverList.push(inputValue)
|
||||
vm.receiverVisible = false
|
||||
vm.receiver = ''
|
||||
} else {
|
||||
this.$message({
|
||||
message: '该账号已经存在',
|
||||
type: 'error'
|
||||
})
|
||||
vm.$refs.saveTagInput.focus()
|
||||
}
|
||||
} else {
|
||||
this.receiverVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-tag {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.button-new-tag {
|
||||
margin-left: 10px;
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.input-new-tag {
|
||||
width: 120px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.message {
|
||||
border: 1px solid #ddd;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
aside {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.tips {
|
||||
border: 1px solid #ddd;
|
||||
margin-left: 18px;
|
||||
}
|
||||
.tips p {
|
||||
text-indent: 20px;
|
||||
padding: 0;
|
||||
margin: 0px;
|
||||
}
|
||||
.article {
|
||||
font-size: 12px;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,431 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.templateId" :placeholder="$t('table.smsTask.templateId')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.topic" :placeholder="$t('table.smsTask.topic')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.content" :placeholder="$t('table.smsTask.content')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t('table.reset') }}</el-button>
|
||||
<router-link :to="{path:'/sms/manage/edit',query: {type: 'add'}}">
|
||||
<el-button v-has-permission="['sms:manage:add']" class="filter-item" plain type="danger">
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
</router-link>
|
||||
<el-dropdown v-has-any-permission="['sms:manage:delete','sms:manage:export']" class="filter-item" trigger="click">
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['sms:manage:delete']" @click.native="batchDelete">{{ $t('table.delete')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['sms:manage:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['sms:manage:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['sms:manage:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.smsTask.templateId')" :show-overflow-tooltip="true" align="center"
|
||||
prop="templateId" width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.templateId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.smsTask.receiver')" :show-overflow-tooltip="true" align="center"
|
||||
prop="receiver"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.receiver }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTask.topic')" :show-overflow-tooltip="true" align="center" width="100px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.topic }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTask.content')" :show-overflow-tooltip="true" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.content }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false" :filters="statusFilters" :label="$t('table.smsTask.status')"
|
||||
:show-overflow-tooltip="true" class-name="status-col" column-key="status"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.sendTime">
|
||||
<el-tooltip :content="'发送时间: '+ scope.row.sendTime" class="item" effect="dark" placement="top">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status.desc }}</el-tag>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span v-else>
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status.desc }}</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="[{ text: $t('common.yes'), value: 'true' }, { text: $t('common.no'), value: 'false' }]"
|
||||
:label="$t('table.smsTask.draft')"
|
||||
align="center"
|
||||
column-key="draft"
|
||||
prop="draft"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-tag slot :type="scope.row.draft?'danger':'success'">{{ scope.row.draft ? '是' : '否' }}</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" align="center" sortable="custom"
|
||||
prop="createTime"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" align="center" column-key="operation"
|
||||
class-name="small-padding fixed-width" width="100px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i
|
||||
v-hasPermission="['sms:manage:view']" class="el-icon-view table-operation" style="color: #2db7f5;"
|
||||
@click="view(row)"
|
||||
></i>
|
||||
<i
|
||||
v-show="row.draft" v-hasPermission="['sms:manage:update']" class="el-icon-edit table-operation"
|
||||
style="color: #2db7f5;" @click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['sms:manage:add']" class="el-icon-copy-document table-operation" style="color: #909399;"
|
||||
@click="copy(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['sms:manage:delete']" class="el-icon-delete table-operation" style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link
|
||||
v-has-no-permission="['sms:manage:update','sms:manage:delete','sms:manage:add','sms:manage:view']"
|
||||
class="no-perm"
|
||||
>
|
||||
{{ $t('tips.noPermission') }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import smsTaskApi from '@/api/SmsTask.js'
|
||||
import { convertEnum } from '@/utils/utils'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import { downloadFile, initMsgsEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'StationManage',
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, FileImport },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
WAITING: 'danger',
|
||||
SUCCESS: 'success',
|
||||
FAIL: 'error'
|
||||
}
|
||||
return map[status] || 'success'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/msgs/smsTask/import`
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({}),
|
||||
selection: [],
|
||||
// 以下已修改
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: {
|
||||
TaskStatus: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
statusFilters() {
|
||||
return convertEnum(this.enums.TaskStatus)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route'(to) {
|
||||
if (to.path === '/sms/manage') {
|
||||
this.fetch()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initMsgsEnums(['TaskStatus'], this.enums)
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出用户数据'
|
||||
smsTaskApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出用户数据'
|
||||
smsTaskApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach((u) => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
smsTaskApi.delete({ 'ids': ids })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
copy(row) {
|
||||
this.$router.push({
|
||||
path: '/sms/manage/edit',
|
||||
query: {
|
||||
id: row.id,
|
||||
type: 'copy'
|
||||
}
|
||||
})
|
||||
},
|
||||
view(row) {
|
||||
this.$router.push({
|
||||
path: '/sms/manage/edit',
|
||||
query: {
|
||||
id: row.id,
|
||||
type: 'view'
|
||||
}
|
||||
})
|
||||
},
|
||||
edit(row) {
|
||||
this.$router.push({
|
||||
path: '/sms/manage/edit',
|
||||
query: {
|
||||
id: row.id,
|
||||
type: 'edit'
|
||||
}
|
||||
})
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
smsTaskApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,249 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.receiver" :placeholder="$t('table.smsSendStatus.receiver')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input
|
||||
v-model="queryParams.model.bizId" :placeholder="$t('table.smsSendStatus.bizId')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-input v-model="queryParams.model.ext" :placeholder="$t('table.smsSendStatus.ext')" class="filter-item search-item" />
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t('table.reset') }}</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.smsSendStatus.receiver')" :show-overflow-tooltip="true" align="center"
|
||||
prop="receiver" width="120px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.receiver }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="sendStatusFilters"
|
||||
:label="$t('table.smsSendStatus.sendStatus')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
column-key="sendStatus"
|
||||
prop="sendStatus"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sendStatus.desc }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="$t('table.smsSendStatus.bizId')" :show-overflow-tooltip="true" align="center"
|
||||
prop="bizId"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.bizId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.smsSendStatus.ext')" :show-overflow-tooltip="true" align="center"
|
||||
prop="ext"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.ext }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.smsSendStatus.code')" :show-overflow-tooltip="true" align="center"
|
||||
prop="code"
|
||||
width="120px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsSendStatus.message')" :show-overflow-tooltip="true" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.message }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsSendStatus.fee')" align="center" width="80px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.fee }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" align="center" prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)" @pagination="fetch"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import smsSendStatusApi from '@/api/SmsSendStatus.js'
|
||||
import { convertEnum } from '@/utils/utils'
|
||||
import { initMsgsEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'SmsSendStatusManage',
|
||||
components: { Pagination },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
false: 'danger',
|
||||
true: 'success'
|
||||
}
|
||||
return map[status] || 'success'
|
||||
}
|
||||
},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: { taskId: 0 }
|
||||
}),
|
||||
selection: [],
|
||||
// 以下已修改
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: { SendStatus: {}}
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sendStatusFilters() {
|
||||
return convertEnum(this.enums.SendStatus)
|
||||
},
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
// this.close()
|
||||
// this.reset()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initMsgsEnums('SendStatus', this.enums)
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
setTaskId(taskId) {
|
||||
this.queryParams.model.taskId = taskId
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
const taskId = this.queryParams.model.taskId
|
||||
this.queryParams = initQueryParams({
|
||||
model: { taskId: taskId }
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
smsSendStatusApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false" :close-on-press-escape="true" :title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible" :width="width" top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form" :model="smsTemplate" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.smsTemplate.providerType')" prop="providerType">
|
||||
<el-select v-model="smsTemplate.providerType.code" placeholder style="width:100%" value>
|
||||
<el-option v-for="(item, key, index) in enums.ProviderType" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.appId')" prop="appId">
|
||||
<el-input v-model="smsTemplate.appId" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.appSecret')" prop="appSecret">
|
||||
<el-input v-model="smsTemplate.appSecret" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.url')" prop="url">
|
||||
<el-input v-model="smsTemplate.url" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.customCode')" prop="customCode">
|
||||
<el-input v-model="smsTemplate.customCode" :disabled="type === 'edit'" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.name')" prop="name">
|
||||
<el-input v-model="smsTemplate.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.content')" prop="content">
|
||||
<el-input v-model="smsTemplate.content" />
|
||||
<aside>
|
||||
百度云:使用 ${xx} 作为占位符
|
||||
<br />
|
||||
阿里云:使用 ${xx} 作为占位符
|
||||
<br />
|
||||
腾讯云:使用 {xx} 作为占位符
|
||||
</aside>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.templateCode')" prop="templateCode">
|
||||
<el-input v-model="smsTemplate.templateCode" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.signName')" prop="signName">
|
||||
<el-input v-model="smsTemplate.signName" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.smsTemplate.templateDescribe')" prop="templateDescribe">
|
||||
<el-input v-model="smsTemplate.templateDescribe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import smsTemplateApi from '@/api/SmsTemplate.js'
|
||||
|
||||
export default {
|
||||
name: 'SmsTemplateEdit',
|
||||
components: {},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
smsTemplate: this.initSmsTemplate(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
enums: {
|
||||
ProviderType: {}
|
||||
},
|
||||
rules: {
|
||||
providerType: [{ required: true, message: this.$t('rules.require'), trigger: 'change' }],
|
||||
appId: [{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range4to10'), trigger: 'blur' }],
|
||||
appSecret: [{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range4to10'), trigger: 'blur' }],
|
||||
customCode: [
|
||||
{ min: 0, max: 20, message: this.$t('rules.range4to10'), trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.type === 'add' && value.trim() !== '') {
|
||||
smsTemplateApi.check(value)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.data) {
|
||||
callback('自定义编码重复')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'blur'
|
||||
}
|
||||
],
|
||||
content: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
templateCode: { required: true, message: this.$t('rules.require'), trigger: 'blur' }
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title () {
|
||||
return this.type === 'add' ? this.$t('common.add') : this.$t('common.edit')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initSmsTemplate () {
|
||||
return {
|
||||
id: '',
|
||||
providerType: { code: '' },
|
||||
appId: '',
|
||||
appSecret: '',
|
||||
url: '',
|
||||
customCode: '',
|
||||
name: '',
|
||||
content: '',
|
||||
templateParams: '',
|
||||
templateCode: '',
|
||||
signName: '',
|
||||
templateDescribe: ''
|
||||
}
|
||||
},
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return '90%'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '45%'
|
||||
} else {
|
||||
return '800px'
|
||||
}
|
||||
},
|
||||
loadListOptions ({ callback }) {
|
||||
callback()
|
||||
},
|
||||
setSmsTemplate (val = {}) {
|
||||
const vm = this
|
||||
if (val['row']) {
|
||||
vm.smsTemplate = { ...val['row'] }
|
||||
}
|
||||
vm.enums = val['enums']
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset () {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.smsTemplate = this.initSmsTemplate()
|
||||
},
|
||||
submitForm () {
|
||||
const vm = this
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit () {
|
||||
const vm = this
|
||||
if (vm.type === 'add') {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save () {
|
||||
const vm = this
|
||||
smsTemplateApi.save(this.smsTemplate)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
vm.$emit('success')
|
||||
}
|
||||
})
|
||||
},
|
||||
update () {
|
||||
smsTemplateApi.update(this.smsTemplate)
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.$emit('success')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
aside {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,401 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="queryParams.model.appId" :placeholder="$t('table.smsTemplate.appId')" size="small" class="filter-item search-item" />
|
||||
<el-input v-model="queryParams.model.customCode" :placeholder="$t('table.smsTemplate.customCode')" size="small" class="filter-item search-item" />
|
||||
<el-input v-model="queryParams.model.name" :placeholder="$t('table.smsTemplate.name')" size="small" class="filter-item search-item" />
|
||||
<el-input v-model="queryParams.model.templateCode" :placeholder="$t('table.smsTemplate.templateCode')" size="small" class="filter-item search-item" />
|
||||
<el-input v-model="queryParams.model.signName" :placeholder="$t('table.smsTemplate.signName')" size="small" class="filter-item search-item" />
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
size="small"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button
|
||||
size="small" class="filter-item" plain
|
||||
type="primary"
|
||||
@click="search"
|
||||
>{{ $t('table.search') }}</el-button>
|
||||
<el-button
|
||||
size="small" class="filter-item" plain
|
||||
type="warning"
|
||||
@click="reset"
|
||||
>{{ $t('table.reset') }}</el-button>
|
||||
<el-button
|
||||
v-has-permission="['sms:template:add']" size="small" class="filter-item"
|
||||
plain
|
||||
type="danger" @click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown v-has-any-permission="['sms:template:delete','sms:template:export']" class="filter-item" trigger="click">
|
||||
<el-button size="small">
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['sms:template:delete']" @click.native="batchDelete">{{ $t('table.delete') }}</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['sms:template:export']" @click.native="exportExcel">{{ $t('table.export') }}</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['sms:template:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['sms:template:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" />
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="providerTypeFilters"
|
||||
column-key="providerType"
|
||||
:label="$t('table.smsTemplate.providerType')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="providerType"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.providerType.desc }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTemplate.appId')" :show-overflow-tooltip="true" align="center" prop="appId">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.appId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTemplate.appSecret')" :show-overflow-tooltip="true" align="center" prop="appSecret">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.appSecret }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.smsTemplate.name')" :show-overflow-tooltip="true" align="center"
|
||||
prop="name"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTemplate.customCode')" :show-overflow-tooltip="true" align="center" prop="customCode">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.customCode }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTemplate.templateCode')" align="center" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.templateCode }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTemplate.signName')" align="center" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.signName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.smsTemplate.templateDescribe')" align="center" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.templateDescribe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')" align="center" prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')" align="center" column-key="operation"
|
||||
class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
<i v-hasPermission="['sms:template:update']" class="el-icon-edit table-operation" style="color: #2db7f5;" @click="edit(row)"></i>
|
||||
<i v-hasPermission="['sms:template:delete']" class="el-icon-delete table-operation" style="color: #f50;" @click="singleDelete(row)"></i>
|
||||
<el-link v-has-no-permission="['sms:template:update','sms:template:delete']" class="no-perm">{{ $t('tips.noPermission') }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total>0" :limit.sync="queryParams.size" :page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<sms-template-edit
|
||||
ref="edit" :dialog-visible="dialog.isVisible" :type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import SmsTemplateEdit from './Edit'
|
||||
import smsTemplateApi from '@/api/SmsTemplate.js'
|
||||
import { convertEnum } from '@/utils/utils'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import { downloadFile, initDicts, initMsgsEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'SmsTemplateManage',
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, SmsTemplateEdit, FileImport },
|
||||
filters: {
|
||||
statusFilter (status) {
|
||||
const map = {
|
||||
false: 'danger',
|
||||
true: 'success'
|
||||
}
|
||||
return map[status] || 'success'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: 'add'
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/msgs/smsTemplate/import`
|
||||
},
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: {
|
||||
ProviderType: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
providerTypeFilters () {
|
||||
return convertEnum(this.enums.ProviderType)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
initMsgsEnums(['ProviderType'], this.enums)
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
editClose () {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess () {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange (selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search () {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset () {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出用户数据'
|
||||
smsTemplateApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出用户数据'
|
||||
smsTemplateApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete (row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete () {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noDataSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach((u) => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
}).catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections () {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete (ids) {
|
||||
smsTemplateApi.delete({ ids: ids })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add () {
|
||||
this.dialog.type = 'add'
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setSmsTemplate({ enums: this.enums })
|
||||
},
|
||||
edit (row) {
|
||||
this.$refs.edit.setSmsTemplate({ row, enums: this.enums })
|
||||
this.dialog.type = 'edit'
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch (params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
smsTemplateApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div class="org">
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="label" :placeholder="$t('table.org.label')" class="filter-item search-item" />
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t('table.reset') }}</el-button>
|
||||
<el-button
|
||||
v-has-permission="['org:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>{{
|
||||
$t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['org:delete','org:export', 'org:import']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t('table.more') }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['org:delete']" @click.native="deleteOrg">{{ $t('table.delete') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['org:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['org:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['org:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-tree
|
||||
ref="orgTree" :check-strictly="true" :data="orgTree"
|
||||
:filter-node-method="filterNode"
|
||||
default-expand-all highlight-current node-key="id"
|
||||
show-checkbox @node-click="nodeClick"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ org.id === '' ? this.$t('common.add') : this.$t('common.edit') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-form
|
||||
ref="form" :model="org" :rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.org.parentId')" prop="parentId">
|
||||
<el-tooltip :content="$t('tips.topId')" class="item" effect="dark" placement="top-start">
|
||||
<el-input v-model="org.parentId" readonly />
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.org.label')" prop="label">
|
||||
<el-input v-model="org.label" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.org.abbreviation')" prop="abbreviation">
|
||||
<el-input v-model="org.abbreviation" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.org.describe')" prop="describe">
|
||||
<el-input v-model="org.describe" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.org.status')" prop="status">
|
||||
<el-radio-group v-model="org.status">
|
||||
<el-radio :label="true">{{ $t('common.status.valid') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('common.status.invalid') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.org.sortValue')" prop="sortValue">
|
||||
<el-input-number v-model="org.sortValue" :max="100" :min="0" @change="handleNumChange" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top: -2rem;">
|
||||
<el-row>
|
||||
<el-col :span="24" style="text-align: right">
|
||||
<el-button plain type="primary" @click="submit">{{ org.id === '' ? this.$t('common.add') :
|
||||
this.$t('common.edit') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import orgApi from '@/api/Org.js'
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import { downloadFile } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: 'OrgManager',
|
||||
directives: { elDragDialog },
|
||||
components: { FileImport },
|
||||
data() {
|
||||
return {
|
||||
label: '',
|
||||
orgTree: [],
|
||||
org: this.initOrg(),
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/authority/org/import`
|
||||
},
|
||||
rules: {
|
||||
label: [
|
||||
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
|
||||
{ min: 1, max: 255, message: this.$t('rules.range3to10'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initOrgTree()
|
||||
},
|
||||
methods: {
|
||||
initOrg() {
|
||||
return {
|
||||
id: '',
|
||||
abbreviation: '',
|
||||
label: '',
|
||||
parentId: 0,
|
||||
status: true,
|
||||
describe: '',
|
||||
sortValue: 0
|
||||
}
|
||||
},
|
||||
initOrgTree() {
|
||||
orgApi.allTree({})
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
this.orgTree = res.data
|
||||
})
|
||||
},
|
||||
exportExcelPreview() {
|
||||
const queryParams = {
|
||||
model: {},
|
||||
map: {
|
||||
fileName: '导出组织数据'
|
||||
},
|
||||
size: 10000
|
||||
}
|
||||
orgApi.preview(queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
const queryParams = {
|
||||
model: {},
|
||||
map: {
|
||||
fileName: '导出组织数据'
|
||||
},
|
||||
size: 10000
|
||||
}
|
||||
orgApi.export(queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.initOrgTree()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
handleNumChange(val) {
|
||||
this.org.sortValue = val
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
},
|
||||
nodeClick(data) {
|
||||
this.org = { ...data }
|
||||
this.$refs.form.clearValidate()
|
||||
},
|
||||
add() {
|
||||
this.resetForm()
|
||||
const checked = this.$refs.orgTree.getCheckedKeys()
|
||||
if (checked.length > 1) {
|
||||
this.$message({
|
||||
message: this.$t('tips.onlyChooseOne'),
|
||||
type: 'warning'
|
||||
})
|
||||
} else if (checked.length > 0) {
|
||||
this.org.parentId = checked[0]
|
||||
} else {
|
||||
this.org.parentId = 0
|
||||
}
|
||||
},
|
||||
deleteOrg() {
|
||||
const checked = this.$refs.orgTree.getCheckedKeys()
|
||||
if (checked.length === 0) {
|
||||
this.$message({
|
||||
message: this.$t('tips.noNodeSelected'),
|
||||
type: 'warning'
|
||||
})
|
||||
} else {
|
||||
this.$confirm(this.$t('tips.confirmDeleteNode'), this.$t('common.tips'), {
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
orgApi.delete({ ids: checked })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$refs.orgTree.setCheckedKeys([])
|
||||
})
|
||||
}
|
||||
},
|
||||
search() {
|
||||
this.$refs.orgTree.filter(this.label)
|
||||
},
|
||||
reset() {
|
||||
this.initOrgTree()
|
||||
this.label = ''
|
||||
this.resetForm()
|
||||
},
|
||||
submit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.org.id) {
|
||||
this.update()
|
||||
} else {
|
||||
this.save()
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
save() {
|
||||
orgApi.save({ ...this.org })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.createSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
update() {
|
||||
orgApi.update({ ...this.org })
|
||||
.then((response) => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t('tips.updateSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.org = this.initOrg()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.org {
|
||||
margin: 10px;
|
||||
|
||||
.app-container {
|
||||
margin: 0 0 10px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
|
||||
.el-card__header {
|
||||
padding: 10px 20px !important;
|
||||
border-bottom: 1px solid #f1f1f1 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
:title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible"
|
||||
:width="width"
|
||||
top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="station"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.station.name')" prop="name">
|
||||
<el-input v-model="station.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.station.orgId')" prop="orgId">
|
||||
<treeselect
|
||||
v-model="station.org.key"
|
||||
:clear-value-text="$t('common.clear')"
|
||||
:load-options="loadListOptions"
|
||||
:multiple="false"
|
||||
:options="orgList"
|
||||
:searchable="true"
|
||||
placeholder=" "
|
||||
style="width:100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.station.status')" prop="status">
|
||||
<el-radio-group v-model="station.status">
|
||||
<el-radio :label="true">{{ $t("common.status.valid") }}</el-radio>
|
||||
<el-radio :label="false">{{ $t("common.status.invalid") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.station.describe')" prop="describe">
|
||||
<el-input v-model="station.describe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{
|
||||
$t("common.cancel")
|
||||
}}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{
|
||||
$t("common.confirm")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import Treeselect from "@riophae/vue-treeselect"
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
|
||||
import stationApi from "@/api/Station.js"
|
||||
|
||||
export default {
|
||||
name: "StationEdit",
|
||||
components: { Treeselect },
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "add"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
remoteStationLoading: false,
|
||||
station: this.initStation(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
orgList: [],
|
||||
stationList: [],
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 255,
|
||||
message: this.$t("rules.range4to10"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!this.station.id) {
|
||||
// this.$get(`system/user/check/${value}`).then((r) => {
|
||||
// if (!r.data) {
|
||||
// callback(this.$t('rules.usernameExist'))
|
||||
// } else {
|
||||
// callback()
|
||||
// }
|
||||
// })
|
||||
} else {
|
||||
// callback()
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
status: {
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "blur"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return this.type === "add"
|
||||
? this.$t("common.add")
|
||||
: this.$t("common.edit")
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
mounted() {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initStation() {
|
||||
return {
|
||||
id: "",
|
||||
name: "",
|
||||
org: {
|
||||
key: null,
|
||||
data: null
|
||||
},
|
||||
status: true,
|
||||
describe: ""
|
||||
}
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return "90%"
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return "45%"
|
||||
} else {
|
||||
return "800px"
|
||||
}
|
||||
},
|
||||
loadListOptions({ callback }) {
|
||||
callback()
|
||||
},
|
||||
setStation(val, orgs) {
|
||||
const vm = this
|
||||
vm.orgList = orgs
|
||||
if (val) {
|
||||
vm.station = { ...val }
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit("close")
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.station = this.initStation()
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
if (vm.type === "add") {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save() {
|
||||
const vm = this
|
||||
stationApi.save(this.station).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t("tips.createSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
vm.$emit("success")
|
||||
}
|
||||
})
|
||||
},
|
||||
update() {
|
||||
stationApi.update(this.station).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t("tips.updateSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
this.$emit("success")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,453 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.name" :placeholder="$t('table.station.name')"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<treeselect
|
||||
v-model="queryParams.model.orgId.key"
|
||||
:clear-value-text="$t('common.clear')"
|
||||
:load-options="loadListOptions"
|
||||
:multiple="false"
|
||||
:options="orgList"
|
||||
:placeholder="$t('table.station.orgId')"
|
||||
:searchable="true"
|
||||
class="filter-item search-item"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">{{ $t("table.search") }}</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">{{ $t("table.reset") }}</el-button>
|
||||
<el-button
|
||||
v-has-permission="['station:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="['station:delete','station:export','station:import']" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['station:delete']" @click.native="batchDelete">
|
||||
{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['station:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['station:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['station:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.station.name')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.station.describe')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="describe"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.describe }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.station.orgId')"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
width="180px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
{{ scope.row.org.data ? scope.row.org.data.label : scope.row.org.key }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
column-key="status"
|
||||
:filters="[
|
||||
{ text: $t('common.status.valid'), value: true },
|
||||
{ text: $t('common.status.invalid'), value: false }
|
||||
]"
|
||||
:label="$t('table.station.status')"
|
||||
class-name="status-col"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag :type="row.status | statusFilter">{{
|
||||
row.status ? $t("common.status.valid") : $t("common.status.invalid")
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.createTime')"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')"
|
||||
align="center"
|
||||
column-key="operation"
|
||||
class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-hasPermission="['station:update']"
|
||||
class="el-icon-edit table-operation"
|
||||
style="color: #2db7f5;"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['station:delete']"
|
||||
class="el-icon-delete table-operation"
|
||||
style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link
|
||||
v-has-no-permission="['station:update', 'station:delete']"
|
||||
class="no-perm"
|
||||
>{{ $t("tips.noPermission") }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<station-edit
|
||||
ref="edit"
|
||||
:dialog-visible="dialog.isVisible"
|
||||
:type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible"
|
||||
:type="fileImport.type" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Treeselect from "@riophae/vue-treeselect"
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import Pagination from "@/components/Pagination"
|
||||
import StationEdit from "./Edit"
|
||||
import stationApi from "@/api/Station.js"
|
||||
import orgApi from "@/api/Org.js"
|
||||
import { downloadFile, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "StationManage",
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, StationEdit, Treeselect, FileImport },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
false: "danger",
|
||||
true: "success"
|
||||
}
|
||||
return map[status] || "success"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: "add"
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/authority/station/import`
|
||||
},
|
||||
tableKey: 0,
|
||||
orgList: [],
|
||||
queryParams: initQueryParams({
|
||||
model: {
|
||||
orgId: {
|
||||
key: null
|
||||
}
|
||||
}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
$route() {
|
||||
if (this.$route.path === "/user/station") {
|
||||
this.initOrg()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initOrg()
|
||||
this.fetch()
|
||||
},
|
||||
methods: {
|
||||
initOrg() {
|
||||
orgApi
|
||||
.allTree({ status: true })
|
||||
.then(response => {
|
||||
const res = response.data
|
||||
this.orgList = res.data
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
message: this.$t("tips.getDataFail"),
|
||||
type: "error"
|
||||
})
|
||||
})
|
||||
},
|
||||
loadListOptions({ callback }) {
|
||||
callback()
|
||||
},
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {
|
||||
orgId: { key: null }
|
||||
}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出岗位数据'
|
||||
stationApi.preview({ ...this.queryParams, ...{ size: 10000 }}).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出岗位数据'
|
||||
stationApi.export({ ...this.queryParams, ...{ size: 10000 }}).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
this.delete(ids)
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
stationApi.delete({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = "add"
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setStation(false, this.orgList)
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setStation(row, this.orgList)
|
||||
this.dialog.type = "edit"
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
stationApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,427 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
:title="title"
|
||||
:type="type"
|
||||
:visible.sync="isVisible"
|
||||
:width="width"
|
||||
top="50px"
|
||||
>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="user"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item :label="$t('table.user.account')" prop="account">
|
||||
<el-input
|
||||
v-model="user.account"
|
||||
:readonly="type === 'add' ? false : 'readonly'"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.name')" prop="name">
|
||||
<el-input v-model="user.name" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-show="type === 'add'"
|
||||
:label="$t('table.user.password')"
|
||||
prop="password"
|
||||
>
|
||||
<el-tooltip
|
||||
:content="$t('tips.defaultPassword')"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-input type="password" value="123456" />
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.avatar')" prop="avatar">
|
||||
<imgUpload
|
||||
ref="imgFileRef"
|
||||
:accept="accept"
|
||||
:accept-size="2 * 1024 * 1024"
|
||||
:auto-upload="true"
|
||||
:data="user.avatar"
|
||||
:file-list="imgFileList"
|
||||
:show-file-list="false"
|
||||
list-type="picture-card"
|
||||
@setId="setIdAndSubmit"
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
</imgUpload>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.orgId')" prop="orgId">
|
||||
<treeselect
|
||||
v-model="user.org.key"
|
||||
:clear-value-text="$t('common.clear')"
|
||||
:load-options="loadListOptions"
|
||||
:multiple="false"
|
||||
:options="orgList"
|
||||
:searchable="true"
|
||||
placeholder=" "
|
||||
style="width:100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.stationId')" prop="stationId">
|
||||
<el-select
|
||||
v-model="user.station.key"
|
||||
:loading="remoteStationLoading"
|
||||
:multiple="false"
|
||||
filterable
|
||||
placeholder="请输入关键词"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in stationList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.email')" prop="email">
|
||||
<el-input v-model="user.email" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.mobile')" prop="mobile">
|
||||
<el-input v-model="user.mobile" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.sex')" prop="sex">
|
||||
<el-select v-model="user.sex.code" placeholder style="width:100%" value>
|
||||
<el-option
|
||||
v-for="(item, key, index) in enums.Sex" :key="index" :label="item"
|
||||
:value="key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.nation')" prop="nation">
|
||||
<el-select v-model="user.nation.key" style="width:100%" :placeholder="$t('table.user.nation')" value>
|
||||
<el-option v-for="(item, key, index) in dicts.NATION" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.education')" prop="education">
|
||||
<el-select v-model="user.education.key" style="width:100%" :placeholder="$t('table.user.education')" value>
|
||||
<el-option v-for="(item, key, index) in dicts.EDUCATION" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.positionStatus')" prop="positionStatus">
|
||||
<el-select v-model="user.positionStatus.key" style="width:100%" :placeholder="$t('table.user.positionStatus')" value>
|
||||
<el-option v-for="(item, key, index) in dicts.POSITION_STATUS" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.status')" prop="status">
|
||||
<el-radio-group v-model="user.status">
|
||||
<el-radio :label="true">{{ $t("common.status.valid") }}</el-radio>
|
||||
<el-radio :label="false">{{ $t("common.status.invalid") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.user.workDescribe')" prop="workDescribe">
|
||||
<el-input v-model="user.workDescribe" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button plain type="warning" @click="isVisible = false">{{
|
||||
$t("common.cancel")
|
||||
}}</el-button>
|
||||
<el-button plain type="primary" @click="submitForm">{{
|
||||
$t("common.confirm")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import { validMobile } from "@/utils/my-validate"
|
||||
import Treeselect from "@riophae/vue-treeselect"
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
|
||||
import imgUpload from "@/components/ceres/imgUpload"
|
||||
import userApi from "@/api/User.js"
|
||||
import stationApi from "@/api/Station.js"
|
||||
|
||||
export default {
|
||||
name: "UserEdit",
|
||||
components: { Treeselect, imgUpload },
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "add"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
accept: "image/jpeg, image/gif, image/png",
|
||||
remoteStationLoading: false,
|
||||
user: this.initUser(),
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
orgList: [],
|
||||
stationList: [],
|
||||
imgFileList: [],
|
||||
imgFileData: {
|
||||
bizId: "",
|
||||
bizType: "USER_AVATAR"
|
||||
},
|
||||
// 图片文件总数
|
||||
imgFileTotal: 0,
|
||||
// 上传成功数
|
||||
successNum: 0,
|
||||
enums: {
|
||||
Sex: {}
|
||||
},
|
||||
dicts: {
|
||||
NATION: {},
|
||||
POSITION_STATUS: {},
|
||||
EDUCATION: {}
|
||||
},
|
||||
rules: {
|
||||
account: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 255,
|
||||
message: this.$t("rules.range4to10"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!this.user.id) {
|
||||
callback()
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
email: {
|
||||
type: "email",
|
||||
message: this.$t("rules.email"),
|
||||
trigger: "blur"
|
||||
},
|
||||
mobile: {
|
||||
validator: (rule, value, callback) => {
|
||||
if (value !== "" && !validMobile(value)) {
|
||||
callback(this.$t("rules.mobile"))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
},
|
||||
sex: {
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "change"
|
||||
},
|
||||
status: {
|
||||
required: true,
|
||||
message: this.$t("rules.require"),
|
||||
trigger: "blur"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set() {
|
||||
this.close()
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
title() {
|
||||
return this.type === "add"
|
||||
? this.$t("common.add")
|
||||
: this.$t("common.edit")
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听deptId
|
||||
"user.org.key": "orgSelect"
|
||||
},
|
||||
mounted() {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
myAvatar(avatar) {
|
||||
if (!avatar) {
|
||||
return require(`@/assets/avatar/default.jpg`)
|
||||
} else {
|
||||
if (avatar.startsWith("http://") || avatar.startsWith("https://")) {
|
||||
return avatar
|
||||
} else {
|
||||
return require(`@/assets/avatar/${avatar}`)
|
||||
}
|
||||
}
|
||||
},
|
||||
initUser() {
|
||||
return {
|
||||
id: "",
|
||||
account: "",
|
||||
name: "",
|
||||
org: {
|
||||
key: null
|
||||
},
|
||||
station: { key: null },
|
||||
email: "",
|
||||
mobile: "",
|
||||
sex: {
|
||||
code: "N"
|
||||
},
|
||||
nation: {
|
||||
key: ""
|
||||
},
|
||||
education: {
|
||||
key: ""
|
||||
},
|
||||
positionStatus: {
|
||||
key: ""
|
||||
},
|
||||
status: true,
|
||||
avatar: "",
|
||||
workDescribe: "",
|
||||
password: "123456"
|
||||
}
|
||||
},
|
||||
initWidth() {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 991) {
|
||||
return "90%"
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return "45%"
|
||||
} else {
|
||||
return "800px"
|
||||
}
|
||||
},
|
||||
|
||||
loadListOptions({ callback }) {
|
||||
callback()
|
||||
},
|
||||
orgSelect(node) {
|
||||
this.loadStation(node)
|
||||
},
|
||||
loadStation(orgId) {
|
||||
this.user.station.key = null
|
||||
if (orgId) {
|
||||
stationApi.page({
|
||||
size: 10000,
|
||||
model: { orgId: { key: orgId }, status: true }
|
||||
}).then(response => {
|
||||
const res = response.data
|
||||
this.stationList = res.data.records
|
||||
})
|
||||
} else {
|
||||
this.stationList = []
|
||||
}
|
||||
},
|
||||
setIdAndSubmit(bizId, url) {
|
||||
const vm = this
|
||||
vm.successNum += 1
|
||||
vm.imgFileData.bizId = bizId
|
||||
vm.user.avatar = url
|
||||
vm.user.id = bizId
|
||||
|
||||
if (vm.successNum === vm.imgFileTotal) {
|
||||
vm.$store.state.hasLoading = false
|
||||
}
|
||||
},
|
||||
setUser(val, orgs, dicts, enums) {
|
||||
const vm = this
|
||||
if (val) {
|
||||
vm.user = { ...val }
|
||||
}
|
||||
vm.dicts = dicts
|
||||
vm.enums = enums
|
||||
|
||||
vm.orgList = orgs
|
||||
vm.imgFileData.bizId = vm.user["id"]
|
||||
vm.$nextTick(() => {
|
||||
vm.$refs.imgFileRef.init({
|
||||
bizId: vm.user["id"],
|
||||
bizType: vm.imgFileData.bizType,
|
||||
imageUrl: vm.myAvatar(vm.user["avatar"]),
|
||||
isSingle: true,
|
||||
isDetail: false
|
||||
})
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.$emit("close")
|
||||
},
|
||||
reset() {
|
||||
// 先清除校验,再清除表单,不然有奇怪的bug
|
||||
this.$refs.form.clearValidate()
|
||||
this.$refs.form.resetFields()
|
||||
this.user = this.initUser()
|
||||
this.imgFileData.bizId = ""
|
||||
this.$refs.imgFileRef.init({
|
||||
bizId: "",
|
||||
bizType: "",
|
||||
imageUrl: "",
|
||||
isSingle: true,
|
||||
isDetail: false
|
||||
})
|
||||
},
|
||||
submitForm() {
|
||||
const vm = this
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
vm.editSubmit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
editSubmit() {
|
||||
const vm = this
|
||||
if (vm.type === "add") {
|
||||
vm.save()
|
||||
} else {
|
||||
vm.update()
|
||||
}
|
||||
},
|
||||
save() {
|
||||
const vm = this
|
||||
userApi.save(this.user).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
vm.isVisible = false
|
||||
vm.$message({
|
||||
message: vm.$t("tips.createSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
vm.$emit("success")
|
||||
}
|
||||
})
|
||||
},
|
||||
update() {
|
||||
userApi.update(this.user).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.isVisible = false
|
||||
this.$message({
|
||||
message: this.$t("tips.updateSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
this.$emit("success")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,705 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParams.model.account"
|
||||
:placeholder="$t('table.user.account')" class="filter-item search-item" clearable
|
||||
/>
|
||||
<el-select
|
||||
v-model="queryParams.model.nation.key" clearable :placeholder="$t('table.user.nation')"
|
||||
class="filter-item search-item"
|
||||
>
|
||||
<el-option v-for="(item, key, index) in dicts.NATION" :key="index" :label="item" :value="key" />
|
||||
</el-select>
|
||||
<treeselect
|
||||
v-model="queryParams.model.org.key"
|
||||
clearable
|
||||
:clear-value-text="$t('common.clear')"
|
||||
:load-options="loadListOptions"
|
||||
:multiple="false"
|
||||
:options="orgList"
|
||||
:searchable="true"
|
||||
class="filter-item search-item"
|
||||
placeholder="组织"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="queryParams.timeRange"
|
||||
:range-separator="null"
|
||||
class="filter-item search-item date-range-item"
|
||||
end-placeholder="结束日期"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
<el-button class="filter-item" plain type="primary" @click="search">
|
||||
{{ $t("table.search") }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" plain type="warning" @click="reset">
|
||||
{{ $t("table.reset") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-has-permission="['user:add']" class="filter-item" plain
|
||||
type="danger"
|
||||
@click="add"
|
||||
>
|
||||
{{ $t("table.add") }}
|
||||
</el-button>
|
||||
<el-dropdown
|
||||
v-has-any-permission="[
|
||||
'user:delete',
|
||||
'user:rest',
|
||||
'user:export',
|
||||
'user:import',
|
||||
]" class="filter-item"
|
||||
trigger="click"
|
||||
>
|
||||
<el-button>
|
||||
{{ $t("table.more") }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-has-permission="['user:delete']" @click.native="batchDelete">
|
||||
{{ $t("table.delete") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['user:reset']" @click.native="resetPassword">
|
||||
{{ $t("table.resetPassword") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['user:export']" @click.native="exportExcel">
|
||||
{{ $t("table.export") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['user:export']" @click.native="exportExcelPreview">
|
||||
{{ $t("table.exportPreview") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permission="['user:import']" @click.native="importExcel">
|
||||
{{ $t("table.import") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:key="tableKey"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="tableData.records"
|
||||
border
|
||||
fit
|
||||
row-key="id" style="width: 100%;" @filter-change="filterChange"
|
||||
@selection-change="onSelectChange"
|
||||
@sort-change="sortChange"
|
||||
@cell-click="cellClick"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40px" :reserve-selection="true" />
|
||||
<el-table-column
|
||||
:label="$t('table.user.avatar')"
|
||||
align="center"
|
||||
prop="avatar"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-avatar
|
||||
:key="scope.row.avatar"
|
||||
:src="myAvatar(scope.row.avatar)"
|
||||
fit="fill"
|
||||
>
|
||||
<el-avatar>{{ scope.row.name | userAvatarFilter }}</el-avatar>
|
||||
</el-avatar>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.account')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="account"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.account }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.name')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
prop="name"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="sexList"
|
||||
column-key="sex.code"
|
||||
:label="$t('table.user.sex')"
|
||||
class-name="status-col"
|
||||
prop="sex.desc"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag :type="row.sex ? row.sex['code'] :'' | sexFilter">{{ row.sex ? row.sex.desc : '' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.email')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.email }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.nation')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.nation['data'] ? scope.row.nation['data'] : scope.row.nation['key'] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="educationList"
|
||||
column-key="education.key"
|
||||
:label="$t('table.user.education')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
width="80px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.education['data'] ? scope.row.education['data'] : scope.row.education['key'] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
:filters="positionStatusList"
|
||||
column-key="positionStatus.key"
|
||||
:label="$t('table.user.positionStatus')"
|
||||
:show-overflow-tooltip="true"
|
||||
align="center"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.positionStatus['data'] ? scope.row.positionStatus['data'] : scope.row.positionStatus['key'] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.orgId')"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{
|
||||
scope.row.org["data"] ? scope.row.org.data.label : scope.row.org.key
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.stationId')"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{
|
||||
scope.row.station["data"]
|
||||
? scope.row.station.data
|
||||
: scope.row.station.key
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filter-multiple="false"
|
||||
column-key="status"
|
||||
:filters="[
|
||||
{ text: $t('common.status.valid'), value: true },
|
||||
{ text: $t('common.status.invalid'), value: false }
|
||||
]"
|
||||
:label="$t('table.user.status')"
|
||||
class-name="status-col"
|
||||
width="70px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag :type="row.status | statusFilter">{{
|
||||
row.status ? $t("common.status.valid") : $t("common.status.invalid")
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.user.createTime')"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
sortable="custom"
|
||||
width="170px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.operation')"
|
||||
align="center"
|
||||
column-key="operation"
|
||||
class-name="small-padding fixed-width"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<i
|
||||
v-hasPermission="['user:view']"
|
||||
class="el-icon-view table-operation"
|
||||
style="color: #87d068;"
|
||||
@click="view(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['user:update']"
|
||||
class="el-icon-edit table-operation"
|
||||
style="color: #2db7f5;"
|
||||
@click="edit(row)"
|
||||
></i>
|
||||
<i
|
||||
v-hasPermission="['user:delete']"
|
||||
class="el-icon-delete table-operation"
|
||||
style="color: #f50;"
|
||||
@click="singleDelete(row)"
|
||||
></i>
|
||||
<el-link
|
||||
v-has-no-permission="['user:view', 'user:update', 'user:delete']"
|
||||
class="no-perm"
|
||||
>{{ $t("tips.noPermission") }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="queryParams.size"
|
||||
:page.sync="queryParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="fetch"
|
||||
/>
|
||||
<user-edit
|
||||
ref="edit"
|
||||
:dialog-visible="dialog.isVisible"
|
||||
:type="dialog.type"
|
||||
@close="editClose"
|
||||
@success="editSuccess"
|
||||
/>
|
||||
<user-view
|
||||
ref="view"
|
||||
:dialog-visible="userViewVisible"
|
||||
@close="viewClose"
|
||||
/>
|
||||
<file-import
|
||||
ref="import"
|
||||
:dialog-visible="fileImport.isVisible" :type="fileImport.type"
|
||||
:export-error-url="fileImport.exportErrorUrl" :action="fileImport.action"
|
||||
accept=".xls,.xlsx"
|
||||
@close="importClose"
|
||||
@success="importSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-el-drag-dialog
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
title="预览"
|
||||
width="80%"
|
||||
top="50px"
|
||||
:visible.sync="preview.isVisible"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<div v-html="preview.context"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from "@/components/Pagination"
|
||||
import Treeselect from "@riophae/vue-treeselect"
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
|
||||
import elDragDialog from '@/directive/el-drag-dialog'
|
||||
import FileImport from "@/components/ceres/Import"
|
||||
import UserEdit from "./Edit"
|
||||
import UserView from "./View"
|
||||
import userApi from "@/api/User.js"
|
||||
import orgApi from "@/api/Org.js"
|
||||
import { convertEnum } from '@/utils/utils'
|
||||
import { downloadFile, initDicts, initEnums, initQueryParams } from '@/utils/commons'
|
||||
|
||||
export default {
|
||||
name: "UserManage",
|
||||
directives: { elDragDialog },
|
||||
components: { Pagination, UserEdit, UserView, Treeselect, FileImport },
|
||||
filters: {
|
||||
userAvatarFilter(name) {
|
||||
return name.charAt(0)
|
||||
},
|
||||
sexFilter(status) {
|
||||
const map = {
|
||||
W: "success",
|
||||
M: "danger",
|
||||
N: "info"
|
||||
}
|
||||
return map[status] || "info"
|
||||
},
|
||||
statusFilter(status) {
|
||||
const map = {
|
||||
false: "danger",
|
||||
true: "success"
|
||||
}
|
||||
return map[status] || "success"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
orgList: [],
|
||||
dialog: {
|
||||
isVisible: false,
|
||||
type: "add"
|
||||
},
|
||||
preview: {
|
||||
isVisible: false,
|
||||
context: ''
|
||||
},
|
||||
fileImport: {
|
||||
isVisible: false,
|
||||
type: "import",
|
||||
action: `${process.env.VUE_APP_BASE_API}/authority/user/import`,
|
||||
exportErrorUrl: `/authority/user/exportError`
|
||||
},
|
||||
userViewVisible: false,
|
||||
tableKey: 0,
|
||||
queryParams: initQueryParams({
|
||||
model: {
|
||||
nation: {
|
||||
key: ''
|
||||
},
|
||||
education: {
|
||||
key: ''
|
||||
},
|
||||
positionStatus: {
|
||||
key: ''
|
||||
},
|
||||
org: {
|
||||
key: null
|
||||
},
|
||||
station: {
|
||||
key: null
|
||||
},
|
||||
sex: {
|
||||
code: ''
|
||||
}
|
||||
}
|
||||
}),
|
||||
selection: [],
|
||||
loading: false,
|
||||
tableData: {
|
||||
total: 0
|
||||
},
|
||||
enums: {
|
||||
Sex: {}
|
||||
},
|
||||
dicts: {
|
||||
NATION: {},
|
||||
POSITION_STATUS: {},
|
||||
EDUCATION: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentUser() {
|
||||
return this.$store.state.account.user
|
||||
},
|
||||
sexList() {
|
||||
return convertEnum(this.enums.Sex)
|
||||
},
|
||||
nationList() {
|
||||
return convertEnum(this.dicts.NATION)
|
||||
},
|
||||
educationList() {
|
||||
return convertEnum(this.dicts.EDUCATION)
|
||||
},
|
||||
positionStatusList() {
|
||||
return convertEnum(this.dicts.POSITION_STATUS)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
if (this.$route.path === "/user/user") {
|
||||
this.initOrg()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
initEnums('Sex', this.enums)
|
||||
initDicts(['NATION', 'POSITION_STATUS', 'EDUCATION'], this.dicts)
|
||||
this.fetch()
|
||||
this.initOrg()
|
||||
},
|
||||
methods: {
|
||||
initOrg() {
|
||||
orgApi.allTree({ status: true }).then(response => {
|
||||
const res = response.data
|
||||
this.orgList = res.data
|
||||
})
|
||||
},
|
||||
myAvatar(avatar) {
|
||||
if (!avatar) {
|
||||
return require(`@/assets/avatar/default.jpg`)
|
||||
} else {
|
||||
if (avatar.startsWith("http://") || avatar.startsWith("https://")) {
|
||||
return avatar
|
||||
} else {
|
||||
return require(`@/assets/avatar/${avatar}`)
|
||||
}
|
||||
}
|
||||
},
|
||||
viewClose() {
|
||||
this.userViewVisible = false
|
||||
},
|
||||
editClose() {
|
||||
this.dialog.isVisible = false
|
||||
},
|
||||
editSuccess() {
|
||||
this.search()
|
||||
},
|
||||
onSelectChange(selection) {
|
||||
this.selection = selection
|
||||
},
|
||||
loadListOptions({ callback }) {
|
||||
callback()
|
||||
},
|
||||
search() {
|
||||
this.fetch({
|
||||
...this.queryParams
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.queryParams = initQueryParams({
|
||||
model: {
|
||||
nation: {
|
||||
key: ''
|
||||
},
|
||||
education: {
|
||||
key: ''
|
||||
},
|
||||
positionStatus: {
|
||||
key: ''
|
||||
},
|
||||
org: {
|
||||
key: null
|
||||
},
|
||||
station: {
|
||||
key: null
|
||||
},
|
||||
sex: {
|
||||
code: ''
|
||||
}
|
||||
}
|
||||
})
|
||||
this.$refs.table.clearSort()
|
||||
this.$refs.table.clearFilter()
|
||||
this.search()
|
||||
},
|
||||
exportExcelPreview() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出用户数据'
|
||||
userApi.preview(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
this.preview.isVisible = true
|
||||
this.preview.context = res.data
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
this.queryParams.map.fileName = '导出用户数据'
|
||||
userApi.export(this.queryParams).then(response => {
|
||||
downloadFile(response)
|
||||
})
|
||||
},
|
||||
importExcel() {
|
||||
this.fileImport.type = "upload"
|
||||
this.fileImport.isVisible = true
|
||||
this.$refs.import.setModel(false)
|
||||
},
|
||||
importSuccess() {
|
||||
this.search()
|
||||
},
|
||||
importClose() {
|
||||
this.fileImport.isVisible = false
|
||||
},
|
||||
resetPassword() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm(
|
||||
this.$t("tips.confirmRestPassword"),
|
||||
this.$t("common.tips"),
|
||||
{
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
ids.push(u.id)
|
||||
})
|
||||
userApi.reset({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.resetPasswordSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.clearSelections()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
singleDelete(row) {
|
||||
this.$refs.table.clearSelection()
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
this.batchDelete()
|
||||
},
|
||||
batchDelete() {
|
||||
if (!this.selection.length) {
|
||||
this.$message({
|
||||
message: this.$t("tips.noDataSelected"),
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
let contain = false
|
||||
this.$confirm(this.$t("tips.confirmDelete"), this.$t("common.tips"), {
|
||||
confirmButtonText: this.$t("common.confirm"),
|
||||
cancelButtonText: this.$t("common.cancel"),
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
const ids = []
|
||||
this.selection.forEach(u => {
|
||||
if (u.id === this.currentUser.id) {
|
||||
contain = true
|
||||
return
|
||||
}
|
||||
ids.push(u.id)
|
||||
})
|
||||
if (contain) {
|
||||
this.$message({
|
||||
message: this.$t("tips.containCurrentUser"),
|
||||
type: "warning"
|
||||
})
|
||||
this.clearSelections()
|
||||
} else {
|
||||
this.delete(ids)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.clearSelections()
|
||||
})
|
||||
},
|
||||
clearSelections() {
|
||||
this.$refs.table.clearSelection()
|
||||
},
|
||||
delete(ids) {
|
||||
userApi.delete({ ids: ids }).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.$message({
|
||||
message: this.$t("tips.deleteSuccess"),
|
||||
type: "success"
|
||||
})
|
||||
}
|
||||
this.search()
|
||||
})
|
||||
},
|
||||
add() {
|
||||
this.dialog.type = "add"
|
||||
this.dialog.isVisible = true
|
||||
this.$refs.edit.setUser(false, this.orgList, this.dicts, this.enums)
|
||||
},
|
||||
view(row) {
|
||||
this.$refs.view.setUser(row, this.orgList, this.dicts, this.enums)
|
||||
this.userViewVisible = true
|
||||
},
|
||||
edit(row) {
|
||||
this.$refs.edit.setUser(row, this.orgList, this.dicts, this.enums)
|
||||
this.dialog.type = "edit"
|
||||
this.dialog.isVisible = true
|
||||
},
|
||||
fetch(params = {}) {
|
||||
this.loading = true
|
||||
if (this.queryParams.timeRange) {
|
||||
this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
|
||||
this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
|
||||
}
|
||||
|
||||
this.queryParams.current = params.current ? params.current : this.queryParams.current
|
||||
this.queryParams.size = params.size ? params.size : this.queryParams.size
|
||||
|
||||
userApi.page(this.queryParams).then(response => {
|
||||
const res = response.data
|
||||
if (res.isSuccess) {
|
||||
this.tableData = res.data
|
||||
}
|
||||
}).finally(() => this.loading = false)
|
||||
},
|
||||
sortChange(val) {
|
||||
this.queryParams.sort = val.prop
|
||||
this.queryParams.order = val.order
|
||||
if (this.queryParams.sort) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
filterChange(filters) {
|
||||
for (const key in filters) {
|
||||
if (key.includes('.')) {
|
||||
const val = {}
|
||||
val[key.split('.')[1]] = filters[key][0]
|
||||
this.queryParams.model[key.split('.')[0]] = val
|
||||
} else {
|
||||
this.queryParams.model[key] = filters[key][0]
|
||||
}
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
cellClick (row, column) {
|
||||
if (column['columnKey'] === "operation") {
|
||||
return
|
||||
}
|
||||
let flag = false
|
||||
this.selection.forEach((item) => {
|
||||
if (item.id === row.id) {
|
||||
flag = true
|
||||
this.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
})
|
||||
if (!flag) {
|
||||
this.$refs.table.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<el-dialog :title="$t('common.view')" :visible.sync="isVisible" :width="width" class="user-view">
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="24" :xs="24">
|
||||
<div class="img-wrapper">
|
||||
<el-avatar :key="user.avatar" :src="user.avatar" fit="fill">
|
||||
<el-avatar>{{ user.name | userAvatarFilter }}</el-avatar>
|
||||
</el-avatar>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-user"></i>
|
||||
<span>{{ $t('table.user.account') +':' }}</span>
|
||||
{{ user.account }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-suitcase"></i>
|
||||
<span>{{ $t('table.user.name') +':' }}</span>
|
||||
{{ user.name }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-user"></i>
|
||||
<span>{{ $t('table.user.email') +':' }}</span>
|
||||
{{ user.email }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-suitcase"></i>
|
||||
<span>{{ $t('table.user.mobile') +':' }}</span>
|
||||
{{ user.mobile }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-trophy"></i>
|
||||
<span>{{ $t('table.user.orgId') +':' }}</span>
|
||||
{{ user.orgId }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-phone-outline"></i>
|
||||
<span>{{ $t('table.user.stationId') +':' }}</span>
|
||||
{{ user.stationId }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-star-off"></i>
|
||||
<span>{{ $t('table.user.sex') +':' }}</span>
|
||||
{{ user.sex.desc }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-bangzhu"></i>
|
||||
<span>{{ $t('table.user.status') +':' }}</span>
|
||||
{{ user.status ? $t('common.status.valid') : $t('common.status.invalid') }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-time"></i>
|
||||
<span>{{ $t('table.user.createTime') +':' }}</span>
|
||||
{{ user.createTime }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-brush"></i>
|
||||
<span>{{ $t('table.user.updateTime') +':' }}</span>
|
||||
{{ user.updateTime }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-date"></i>
|
||||
<span>{{ $t('table.user.lastLoginTime') +':' }}</span>
|
||||
{{ user.lastLoginTime ? user.lastLoginTime: $t('tips.neverLogin') }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-date"></i>
|
||||
<span>{{ $t('table.user.passwordExpireTime') +':' }}</span>
|
||||
{{ user.passwordExpireTime }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-date"></i>
|
||||
<span>{{ $t('table.user.passwordErrorLastTime') +':' }}</span>
|
||||
{{ user.passwordErrorLastTime }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-date"></i>
|
||||
<span>{{ $t('table.user.passwordErrorNum') +':' }}</span>
|
||||
{{ user.passwordErrorNum }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="24" :xs="24">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-document"></i>
|
||||
<span>{{ $t('table.user.workDescribe') +':' }}</span>
|
||||
{{ user.workDescribe ? user.workDescribe: $t('tips.nothing') }}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'UserView',
|
||||
filters: {
|
||||
userAvatarFilter (name) {
|
||||
return name ? name.charAt(0) : '无'
|
||||
}
|
||||
},
|
||||
props: {
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
screenWidth: 0,
|
||||
width: this.initWidth(),
|
||||
user: {
|
||||
sex: {
|
||||
desc: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get () {
|
||||
return this.dialogVisible
|
||||
},
|
||||
set () {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
this.width = this.initWidth()
|
||||
})()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initWidth () {
|
||||
this.screenWidth = document.body.clientWidth
|
||||
if (this.screenWidth < 550) {
|
||||
return '95%'
|
||||
} else if (this.screenWidth < 990) {
|
||||
return '580px'
|
||||
} else if (this.screenWidth < 1400) {
|
||||
return '600px'
|
||||
} else {
|
||||
return '650px'
|
||||
}
|
||||
},
|
||||
setUser (val) {
|
||||
this.user = { ...val }
|
||||
},
|
||||
close () {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.user-view {
|
||||
.img-wrapper {
|
||||
text-align: center;
|
||||
margin-top: -1.5rem;
|
||||
margin-bottom: 10px;
|
||||
img {
|
||||
width: 4rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.view-item {
|
||||
margin: 7px;
|
||||
i {
|
||||
font-size: 0.97rem;
|
||||
}
|
||||
span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<div class="overview_page">
|
||||
<div class="total_info">
|
||||
<ul>
|
||||
<li v-for="(item,index) in totalList" :key="index">
|
||||
<p>{{ item.value }}</p>
|
||||
<p>
|
||||
{{ item.name }}
|
||||
<i class="el-icon-warning-outline icon" :title="item.tips"></i>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<el-form
|
||||
:inline="true"
|
||||
:model="formParams"
|
||||
>
|
||||
<el-form-item label="商家名称">
|
||||
<el-input v-model="formParams.model.tenantName" size="mini" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商家编码">
|
||||
<el-input v-model="formParams.model.tenantCode" size="mini" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="query"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button
|
||||
plain
|
||||
size="mini"
|
||||
@click="reset"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table
|
||||
:data="tableData.records"
|
||||
border
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="tenantName"
|
||||
label="商家名称"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tenantCode"
|
||||
label="商家编码"
|
||||
/>
|
||||
<el-table-column
|
||||
:formatter="getPrice"
|
||||
prop="incomeAmount"
|
||||
label="营收总额"
|
||||
/>
|
||||
<el-table-column
|
||||
:formatter="getPrice"
|
||||
prop="freezesAmount"
|
||||
label="冻结金额"
|
||||
/>
|
||||
<el-table-column
|
||||
:formatter="getPrice"
|
||||
prop="withdrawAmount"
|
||||
label="已提金额"
|
||||
/>
|
||||
<el-table-column
|
||||
:formatter="getPrice"
|
||||
prop="refundAmount"
|
||||
label="已退款金额"
|
||||
/>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:limit.sync="formParams.size"
|
||||
:page.sync="formParams.current"
|
||||
:total="Number(tableData.total)"
|
||||
@pagination="query"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '@/components/Pagination'
|
||||
import Finance from '@/api/Finance'
|
||||
export default {
|
||||
components: {
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formParams: {
|
||||
"current": 1,
|
||||
"map": {},
|
||||
"model": {
|
||||
"canWithdrawAmount": 0,
|
||||
"freezesAmount": 0,
|
||||
"incomeAmount": 0,
|
||||
"refundAmount": 0,
|
||||
"tenantCode": "",
|
||||
"tenantName": "",
|
||||
"withdrawAmount": 0
|
||||
},
|
||||
"order": "descending",
|
||||
"size": 10,
|
||||
"sort": "id"
|
||||
},
|
||||
totalList: [
|
||||
{ name: '营收总额', value: 0, field: 'incomeAmount', tips: '所有商家支付成功的订单总金额' },
|
||||
{ name: '冻结总金额', value: 0, field: 'freezesAmount', tips: '所有商家交易尚未完成仍在冻结中的金额' },
|
||||
{ name: '可提现金额', value: 0, field: 'canWithdrawAmount', tips: '所有商家可以提现但尚未提现的的金额' },
|
||||
{ name: '已提金额', value: 0, field: 'withdrawAmount', tips: '所有商家的售后订单中产生退款并退款成功的总金额' },
|
||||
{ name: '已退款金额', value: 0, field: 'refundAmount', tips: '' }
|
||||
],
|
||||
tableData: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDayList()
|
||||
this.getSummary()
|
||||
},
|
||||
methods: {
|
||||
async getDayList() {
|
||||
const res = await Finance.getDayList(this.formParams)
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
this.tableData = resData.data
|
||||
}
|
||||
},
|
||||
async getSummary() {
|
||||
const res = await Finance.getSummary()
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
const o = resData.data
|
||||
this.totalList.map(item => {
|
||||
item.value = o[item.field] / 100 || 0
|
||||
})
|
||||
}
|
||||
},
|
||||
query() {
|
||||
this.getDayList()
|
||||
},
|
||||
getPrice(item, row, value) {
|
||||
return value / 100
|
||||
},
|
||||
reset() {
|
||||
this.formParams = {
|
||||
"current": 1,
|
||||
"map": {},
|
||||
"model": {
|
||||
"canWithdrawAmount": 0,
|
||||
"freezesAmount": 0,
|
||||
"incomeAmount": 0,
|
||||
"refundAmount": 0,
|
||||
"tenantCode": "",
|
||||
"tenantName": "",
|
||||
"withdrawAmount": 0
|
||||
},
|
||||
"order": "descending",
|
||||
"size": 10,
|
||||
"sort": "id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.overview_page {
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
height: calc(100% -20px);
|
||||
.total_info {
|
||||
border-bottom: 1px solid #E0E5EB;
|
||||
margin-bottom: 20px;
|
||||
ul {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
list-style: none;
|
||||
li {
|
||||
flex: 2.4;
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
p {
|
||||
margin: 0;
|
||||
&:nth-child(1) {
|
||||
font-weight: 600;
|
||||
font-size: 30px;
|
||||
color: #ffae11;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
font-size: 18px;
|
||||
.icon {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-table {
|
||||
th {
|
||||
background: #EEF3FF;
|
||||
color:#333333;
|
||||
font-size:16px;
|
||||
font-weight: 400;
|
||||
border-color: #E0E5EB;
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.cell {
|
||||
text-align: center;
|
||||
white-space: pre-line;/*保留换行符*/
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -20,6 +20,29 @@
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="Number(info.organizationType) !== 1" class="main_info">
|
||||
<p class="detail_title">主体信息</p>
|
||||
<p v-for="(item, index) in mainInfo" :key="index" class="detail_text">
|
||||
<span>
|
||||
<font>*</font>
|
||||
{{ item.name + ':' }}
|
||||
</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</p>
|
||||
<p class="detail_img">
|
||||
<span>
|
||||
<font>*</font>
|
||||
营业执照
|
||||
</span>
|
||||
<img
|
||||
v-for="(src,index) in businessImage" :key="'bussiness' + index" :src="src"
|
||||
:preview="1"
|
||||
/>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="person_info">
|
||||
<p class="detail_title">个人信息</p>
|
||||
<p v-for="(item, index) in personInfoList" :key="index" class="detail_text">
|
||||
@@ -34,15 +57,24 @@
|
||||
<font>*</font>
|
||||
证件照片
|
||||
</span>
|
||||
<img :src="info.idCardCopyFilePath" alt="" />
|
||||
<img :src="info.idCardNationalFilePath" alt="" />
|
||||
<img
|
||||
v-for="(src,index) in idCardCopyFilePath" :key="'id' + index" :src="src"
|
||||
:preview="2"
|
||||
/>
|
||||
<img
|
||||
v-for="(src,index) in idCardNationalFilePath" :key="'idCard' + index" :src="src"
|
||||
:preview="3"
|
||||
/>
|
||||
</p>
|
||||
<p v-if="Number(info.organizationType) === 1" class="detail_img">
|
||||
<span>
|
||||
<font>*</font>
|
||||
手持证件照
|
||||
</span>
|
||||
<img :src="info.handHoldCardPath" alt="" />
|
||||
<img
|
||||
v-for="(src,index) in handHoldCardPath" :key="'hand' + index" :src="src"
|
||||
:preview="4"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -90,8 +122,24 @@ export default {
|
||||
{ name: '生效日期', value: '', field: 'effectTime' },
|
||||
{ name: '生效时限', value: '', field: 'effectTimeLimit' }
|
||||
],
|
||||
mainInfo: [
|
||||
{ name: '商户名称', value: '', field: 'merchantName' },
|
||||
{ name: '社会信用代码', value: '', field: 'socialCreditCode' },
|
||||
{ name: '注册地址', value: '', field: 'companyAddressProvince' },
|
||||
{ name: '营业期限', value: '', field: 'businessTimeStart' }
|
||||
],
|
||||
dialogData: {},
|
||||
info: {}
|
||||
info: {},
|
||||
orgType: {
|
||||
1: '个人',
|
||||
2: '个体工商户',
|
||||
3: '企业',
|
||||
4: '其他组织'
|
||||
},
|
||||
businessImage: [],
|
||||
idCardCopyFilePath: [],
|
||||
idCardNationalFilePath: [],
|
||||
handHoldCardPath: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -111,6 +159,11 @@ export default {
|
||||
const d = resData.data
|
||||
vm.info = d
|
||||
vm.getData(d)
|
||||
vm.businessImage[0] = d.businessLicenseCopyFilePath
|
||||
vm.idCardCopyFilePath[0] = d.idCardCopyFilePath
|
||||
vm.idCardNationalFilePath[0] = d.idCardNationalFilePath
|
||||
vm.handHoldCardPath[0] = d.handHoldCardPath
|
||||
this.$previewRefresh()
|
||||
}
|
||||
},
|
||||
getTitle() {
|
||||
@@ -126,15 +179,11 @@ export default {
|
||||
// const info = vm.$route.query.info
|
||||
vm.getObjData(vm.shopInfoList, info)
|
||||
vm.getObjData(vm.personInfoList, info)
|
||||
vm.getObjData(vm.mainInfo, info)
|
||||
vm.getObjData(vm.authInfoList, info)
|
||||
},
|
||||
getObjData(arr, o) {
|
||||
const t = {
|
||||
1: '个人',
|
||||
2: '个体工商户',
|
||||
3: '企业',
|
||||
4: '其他组织'
|
||||
}
|
||||
const vm = this
|
||||
const ob = {
|
||||
1: '中国大陆居民身份证',
|
||||
2: '中国香港居民来往内地通行证',
|
||||
@@ -142,10 +191,15 @@ export default {
|
||||
4: '中国台湾居民来往内地通行证',
|
||||
5: '其他国家或地区居民护照'
|
||||
}
|
||||
const org = {
|
||||
2: '商户名称',
|
||||
3: '企业名称',
|
||||
4: '组织名称'
|
||||
}
|
||||
arr.map(item => {
|
||||
item.value = o[item.field]
|
||||
if (item.field === 'organizationType') {
|
||||
item.value = t[Number(o.organizationType || '')]
|
||||
item.value = vm.orgType[Number(o.organizationType || '')]
|
||||
}
|
||||
if (item.field === 'storeAddressProvince') {
|
||||
item.value = `${o.storeAddressProvince || ''}${o.storeAddressCity || ''}${o.storeAddressDetail || ''}`
|
||||
@@ -162,6 +216,18 @@ export default {
|
||||
if (item.field === 'effectTime') {
|
||||
item.value = o.effectDateType === 1 ? o.auditTime : o.effectTime
|
||||
}
|
||||
if (item.field === 'merchantName') {
|
||||
item.name = org[Number(o.organizationType || '')]
|
||||
}
|
||||
if (item.field === 'socialCreditCode' ) {
|
||||
item.name = Number(o.organizationType || '') === 4 ? '机构证件' : '营业执照'
|
||||
}
|
||||
if (item.field === 'companyAddressProvince' ) {
|
||||
item.value = `${o.companyAddressProvince || ''}${o.companyAddressCity || ''}${o.companyAddressDistrict || ''}${o.companyAddress || ''}`
|
||||
}
|
||||
if (item.field === 'businessTimeStart') {
|
||||
item.value = `${o.businessTimeStart || ''}──${o.businessTimeEnd || ''}`
|
||||
}
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="生效时限" prop="effectTimeLimit">
|
||||
<el-col :span="22">
|
||||
<el-col :span="18">
|
||||
<el-input v-model.number="form.effectTimeLimit" placeholder="请输入生效时限" />
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
v-if="scope.row.auditState===2 || scope.row.auditState===3"
|
||||
type="text"
|
||||
size="small"
|
||||
@click.native.prevent="details(scope.row)"
|
||||
@click.native.prevent="handle(scope.row)"
|
||||
>
|
||||
详情
|
||||
</el-button>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
@query="query"
|
||||
@addManagement="addManagement"
|
||||
/>
|
||||
<Container :data-list="dataList" />
|
||||
<Container :data-list="dataList" @fetch="fetch" />
|
||||
<Dialog
|
||||
title="新建商家"
|
||||
:visible.sync="dialogVisible"
|
||||
@@ -32,7 +32,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
dataList: [],
|
||||
dataList: {},
|
||||
params: {
|
||||
current: 1,
|
||||
map: {},
|
||||
@@ -65,7 +65,12 @@ export default {
|
||||
async getManagementList() {
|
||||
const res = await Management.getAllTenant(this.params)
|
||||
const resData = res.data
|
||||
this.dataList = resData.data.records || []
|
||||
this.dataList = resData.data || {}
|
||||
},
|
||||
fetch(v) {
|
||||
Object.assign(this.params, v)
|
||||
console.log(this.params, v)
|
||||
this.getManagementList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="empower_page">
|
||||
<div class="top_btn">
|
||||
菜单赋权
|
||||
<el-button type="primary" class="save_btn" :loading="loading" @click="save">保存</el-button>
|
||||
</div>
|
||||
<div class="empower_content">
|
||||
<!-- <div class="item">
|
||||
<div class="top_box">
|
||||
平台菜单
|
||||
<el-select v-model="type" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="menu_tree">
|
||||
<el-tree
|
||||
ref="platFormTree"
|
||||
:data="platFormMenu"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
node-key="id"
|
||||
highlight-current
|
||||
:props="defaultProps"
|
||||
/>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <div class="item">
|
||||
<div class="btn_list">
|
||||
<p @click="empower">
|
||||
<img :src="right" alt="" />
|
||||
</p>
|
||||
<p @click="recycleMenu">
|
||||
<img :src="left" alt="" />
|
||||
</p>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="item">
|
||||
<div class="top_box">
|
||||
<el-form inline label-width="100px">
|
||||
<el-form-item class="select_type">
|
||||
<el-select v-model="type" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="type" label="商家编号">
|
||||
<el-col :span="15">
|
||||
<el-input v-model="form.tenantCode" placeholder="请输入商家编号" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button @click="getSpecialMerchantMenu">搜索</el-button>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="menu_tree">
|
||||
<el-checkbox v-model="checked" @change="changeCheck">全选</el-checkbox>
|
||||
<el-tree
|
||||
ref="merchantTree"
|
||||
:data="form.menuList"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
node-key="id"
|
||||
highlight-current
|
||||
:props="defaultProps"
|
||||
@check-change="checkChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Menu from '@/api/Menu'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checked: false,
|
||||
loading: false,
|
||||
options: [
|
||||
{ label: '同步所有商家', value: 0 },
|
||||
{ label: '同步指定商家', value: 1 }
|
||||
],
|
||||
type: 0,
|
||||
tenantCode: '',
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
},
|
||||
platFormMenu: [],
|
||||
mechantMenu: [],
|
||||
selected: [],
|
||||
form: {
|
||||
menuList: [],
|
||||
tenantCode: null
|
||||
},
|
||||
allKeys: []
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
left () {
|
||||
return require('@/assets/menu-left.png')
|
||||
},
|
||||
right () {
|
||||
return require('@/assets/menu-right.png')
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.getPlatformMenu()
|
||||
this.getAllMerchanMenu()
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
changeCheck(v) {
|
||||
if (v) {
|
||||
this.$refs.merchantTree.setCheckedKeys(this.allKeys)
|
||||
} else {
|
||||
this.$refs.merchantTree.setCheckedKeys([])
|
||||
}
|
||||
},
|
||||
async getPlatformMenu() {
|
||||
const res = await Menu.getPlatformMenu()
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
this.platFormMenu = resData.data
|
||||
}
|
||||
},
|
||||
async getAllMerchanMenu() {
|
||||
const res = await Menu.getAllMerchanMenu()
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
const t = resData.data
|
||||
this.changeTreeData(t)
|
||||
this.form.menuList = t
|
||||
this.getSelected(t)
|
||||
this.$nextTick(() => {
|
||||
this.setCheckedNodes()
|
||||
})
|
||||
}
|
||||
},
|
||||
changeTreeData(data) {
|
||||
if (data && data.length) {
|
||||
data.map(item => {
|
||||
if (item.children && item.children.length && (item.children.findIndex(k => k.isSync === 0) > -1)) {
|
||||
item.isSync = 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
// 获取指定商家的菜单
|
||||
async getSpecialMerchantMenu() {
|
||||
const res = await Menu.getSpecialMerchantMenu(this.form.tenantCode)
|
||||
const resData = res.data
|
||||
if (resData.code === 0) {
|
||||
this.form.menuList = resData.data
|
||||
}
|
||||
},
|
||||
save() {
|
||||
this.loading = true
|
||||
Menu.saveMenu(this.form).then(res => {
|
||||
this.loading = false
|
||||
if (res.data.code === 0) {
|
||||
this.$message.success('菜单同步成功')
|
||||
}
|
||||
})
|
||||
},
|
||||
getSelected(data) {
|
||||
const t = []
|
||||
const arr = []
|
||||
if (data && data.length) {
|
||||
data.forEach(item => {
|
||||
if (item.isSync) {
|
||||
t.push(item.id)
|
||||
}
|
||||
arr.push(item.id)
|
||||
if (item.children && item.children.length) {
|
||||
item.children.forEach(ob => {
|
||||
if (ob.isSync) {
|
||||
t.push(ob.id)
|
||||
}
|
||||
arr.push(ob.id)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
this.selected = t
|
||||
this.allKeys = arr
|
||||
if (t.length === arr.length) {
|
||||
this.checked = true
|
||||
}
|
||||
},
|
||||
setCheckedNodes() {
|
||||
if (this.selected.length) {
|
||||
this.$refs.merchantTree.setCheckedKeys(this.selected)
|
||||
}
|
||||
},
|
||||
checkChange(a, b, c, d) {
|
||||
a.isSync = b ? 1 : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
.empower_page {
|
||||
min-height: 500px;
|
||||
margin-top:20px;
|
||||
padding: 20px;
|
||||
background-color: #ffffff;
|
||||
|
||||
.top_btn {
|
||||
height: 50px;
|
||||
font-size: 20px;
|
||||
line-height: 50px;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px #E0E5EB solid;
|
||||
.save_btn {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.empower_content {
|
||||
// overflow: hidden;
|
||||
.item {
|
||||
min-height: 700px;
|
||||
// float: left;
|
||||
box-sizing: border-box;
|
||||
&:nth-child(1), &:nth-child(3) {
|
||||
// width:calc(50% - 75px);
|
||||
width: 50%;
|
||||
margin: 20px auto;
|
||||
background:rgba(255,255,255,1);
|
||||
box-shadow:0px 0px 10px 0px rgba(51,51,51,0.15);
|
||||
// border: 1px #E0E5EB solid;
|
||||
border-radius:4px;
|
||||
.top_box {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
font-size: 18px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
background-color: #F7F7F7;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.menu_tree {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 150px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
.btn_list {
|
||||
height: 150px;
|
||||
width: 40px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -75px;
|
||||
margin-left: -20px;
|
||||
p {
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
background-color: #EEEEEE;
|
||||
border-radius:4px;
|
||||
padding-top: 18px;
|
||||
img {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select_type {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/deep/.el-form {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/deep/.el-form-item {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/deep/.select_type {
|
||||
float: left;
|
||||
}
|
||||
/deep/.el-form-item__content {
|
||||
line-height: 60px !important;
|
||||
}
|
||||
/deep/ label {
|
||||
font-weight: 400;
|
||||
}
|
||||
/deep/.el-col-6 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user