88 changed files with 18057 additions and 26 deletions
@ -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 |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
@ -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 |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
@ -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 |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
@ -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 |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 598 B |
|
After Width: | Height: | Size: 610 B |
@ -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> |
||||||
@ -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> |
||||||
@ -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> |
||||||
Loading…
Reference in new issue