Merge branch 'projects/mes-test' into projects/mes-zhp

This commit is contained in:
‘937886381’ 2024-08-13 08:36:54 +08:00
commit 2213b93f0a
117 changed files with 24343 additions and 11539 deletions

View File

@ -0,0 +1,76 @@
/*
* @Author: zwq
* @Date: 2023-11-02 16:20:15
* @LastEditors: zwq
* @LastEditTime: 2024-08-09 09:55:56
* @Description:
*/
import request from '@/utils/request'
// 创建库区设置
export function createWarehouseArea(data) {
return request({
url: '/extend/warehouse-area/create',
method: 'post',
data: data
})
}
// 更新库区设置
export function updateWarehouseArea(data) {
return request({
url: '/extend/warehouse-area/update',
method: 'put',
data: data
})
}
// 删除库区设置
export function deleteWarehouseArea(id) {
return request({
url: '/extend/warehouse-area/delete?id=' + id,
method: 'delete'
})
}
// 获得库区设置
export function getWarehouseArea(id) {
return request({
url: '/extend/warehouse-area/get?id=' + id,
method: 'get'
})
}
// 获得库区设置列表
export function getWarehouseAreaList(id) {
return request({
url: '/extend/warehouse-area/listAll?warehouseId=' + id,
method: 'get'
})
}
// 获得库区设置分页
export function getWarehouseAreaPage(query) {
return request({
url: '/extend/warehouse-area/page',
method: 'get',
params: query,
})
}
// 获得code
export function getCode() {
return request({
url: '/extend/warehouse-area/getCode',
method: 'get'
})
}
// 导出库区设置 Excel
export function exportWarehouseAreaExcel(query) {
return request({
url: '/extend/warehouse-area/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@ -0,0 +1,84 @@
/*
* @Author: zwq
* @Date: 2023-11-02 16:20:15
* @LastEditors: zwq
* @LastEditTime: 2024-08-08 15:56:30
* @Description:
*/
import request from '@/utils/request'
// 创建库位设置
export function createWarehouseLocation(data) {
return request({
url: '/extend/warehouse-location/create',
method: 'post',
data: data
})
}
// 更新库位设置
export function updateWarehouseLocation(data) {
return request({
url: '/extend/warehouse-location/update',
method: 'put',
data: data
})
}
// 删除库位设置
export function deleteWarehouseLocation(id) {
return request({
url: '/extend/warehouse-location/delete?id=' + id,
method: 'delete'
})
}
// 获得库位设置
export function getWarehouseLocation(id) {
return request({
url: '/extend/warehouse-location/get?id=' + id,
method: 'get'
})
}
// 获得库位设置列表
export function getWarehouseLocationTree() {
return request({
url: '/extend/warehouse-location/getTree',
method: 'get'
})
}
// 获得库位设置列表
export function getWarehouseLocationList() {
return request({
url: '/extend/warehouse-location/listAll',
method: 'get'
})
}
// 获得库位设置分页
export function getWarehouseLocationPage(data) {
return request({
url: '/extend/warehouse-location/page',
method: 'POST',
data: data
})
}
// 获得code
export function getCode() {
return request({
url: '/extend/warehouse-location/getCode',
method: 'get'
})
}
// 导出库位设置 Excel
export function exportWarehouseLocationExcel(query) {
return request({
url: '/extend/warehouse-location/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@ -0,0 +1,84 @@
/*
* @Author: zwq
* @Date: 2023-11-02 16:20:15
* @LastEditors: zwq
* @LastEditTime: 2024-07-30 14:14:48
* @Description:
*/
import request from '@/utils/request'
// 创建仓库设置
export function createWarehouse(data) {
return request({
url: '/extend/warehouse/create',
method: 'post',
data: data
})
}
// 更新仓库设置
export function updateWarehouse(data) {
return request({
url: '/extend/warehouse/update',
method: 'put',
data: data
})
}
// 删除仓库设置
export function deleteWarehouse(id) {
return request({
url: '/extend/warehouse/delete?id=' + id,
method: 'delete'
})
}
// 获得仓库设置
export function getWarehouse(id) {
return request({
url: '/extend/warehouse/get?id=' + id,
method: 'get'
})
}
// 获得仓库设置列表
export function getWarehouseList() {
return request({
url: '/extend/warehouse/listAll',
method: 'get'
})
}
// 获得仓库首页统计信息
export function getWarehouseAllInfo() {
return request({
url: '/extend/warehouse/getAllInfo',
method: 'get'
})
}
// 获得仓库设置分页
export function getWarehousePage(query) {
return request({
url: '/extend/warehouse/page',
method: 'get',
params: query,
})
}
// 获得code
export function getCode() {
return request({
url: '/extend/warehouse/getCode',
method: 'get'
})
}
// 导出仓库设置 Excel
export function exportWarehouseExcel(query) {
return request({
url: '/extend/warehouse/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2023-11-02 14:31:42 * @Date: 2023-11-02 14:31:42
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2023-11-04 14:56:10 * @LastEditTime: 2024-08-02 15:51:37
* @Description: * @Description:
*/ */
import request from '@/utils/request' import request from '@/utils/request'
@ -41,10 +41,11 @@ export function getWarehouseLocation(id) {
}) })
} }
// 获得库位列表(通过仓库id) // 获得库位列表(通过仓库id)
export function listByWarehouse(id) { export function listByWarehouse(query) {
return request({ return request({
url: '/extend/warehouse-location/listByWarehouse?warehouseId=' + id, url: '/extend/warehouse-location/listByWarehouse',
method: 'get' method: 'get',
params: query,
}) })
} }
// 获得库位列表(All) // 获得库位列表(All)

View File

@ -25,6 +25,22 @@ export function outWarehouseRealtimeLocation(data) {
data: data data: data
}) })
} }
// 出入库-有库位 > 移库操作
export function moveWarehouseRealtimeLocation(data) {
return request({
url: '/extend/warehouse-realtime-location/move',
method: 'post',
data: data
})
}
// 出入库-有库位 > 批量出库操作
export function outWarehouseRealtimeLocationList(data) {
return request({
url: '/extend/warehouse-realtime-location/outList',
method: 'post',
data: data
})
}
// 出入库-有库位 > 入库操作 // 出入库-有库位 > 入库操作
export function inWarehouseRealtimeLocation(data) { export function inWarehouseRealtimeLocation(data) {
@ -68,7 +84,16 @@ export function getWarehouseRealtimeLocationPage(data) {
// 获得出入库历史-有库位分页 // 获得出入库历史-有库位分页
export function getWarehouseLocationHisPage(data) { export function getWarehouseLocationHisPage(data) {
return request({ return request({
url: '/extend/warehouse-location-his/page', url: '/extend/warehouse-location-his/inAndOutPage',
method: 'post',
data: data
})
}
// 获得移库历史-有库位分页
export function getMoveHisPage(data) {
return request({
url: '/extend/warehouse-location-his/movePage',
method: 'post', method: 'post',
data: data data: data
}) })

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>切片</title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.300397">
<g id="异常警告" transform="translate(-1468.000000, -122.000000)" fill="#000000" fill-rule="nonzero">
<g id="编组" transform="translate(1468.000000, 122.000000)">
<rect id="矩形" opacity="0" x="0" y="0" width="20" height="20"></rect>
<path d="M9.30923195,2.02433324 C9.77491134,1.74507539 10.3606909,1.77046228 10.8045305,2.10049178 L16.9348344,6.65833873 L17.0554341,6.75466057 C17.5620417,7.18880359 17.858553,7.83620671 17.858553,8.52258247 L17.858553,15.8725474 L17.8541939,16.0176907 C17.7819026,17.2175976 16.8194895,18.1676569 15.6429193,18.1676569 L4.35708075,18.1676569 L4.21696353,18.1631414 C3.05860736,18.088257 2.14144699,17.0913218 2.14144699,15.8725474 L2.14144699,8.52279895 L2.14667089,8.36514909 C2.19177438,7.68568874 2.52672869,7.05865465 3.06516484,6.65833926 L9.19546584,2.10049447 Z M10.0594243,2.9649471 C9.98106349,2.94811965 9.89748036,2.96494528 9.8295714,3.01542217 L3.69926285,7.57327258 L3.6053427,7.65125711 C3.36716077,7.8716339 3.22876238,8.18810985 3.22876238,8.52279895 L3.22876238,15.8725474 L3.2339275,15.9851099 C3.28860185,16.5778056 3.77058378,17.041339 4.35708075,17.041339 L9.37562475,17.0406466 L9.45894699,16.9543314 L9.45935013,12.0522655 L9.46519481,11.973647 C9.50370053,11.7169857 9.72785233,11.5189729 10,11.5189729 C10.2788031,11.5189729 10.5102651,11.7278709 10.5378921,11.998001 L10.5407652,12.056799 L10.5406137,16.9543234 L10.6239359,17.0406466 L15.6429082,17.041339 L15.7515746,17.0359886 C16.3237555,16.9793531 16.7712376,16.4800823 16.7712376,15.8725474 L16.7712376,8.52279895 L16.7648256,8.39829639 C16.7308293,8.06937748 16.5632607,7.76840693 16.3007289,7.57326642 L10.1704369,3.01542833 L10.1168893,2.98387768 Z" id="形状结合" stroke="#000000" stroke-width="0.1"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="3-设备管理-设备保养-保养项目设置" transform="translate(-1713.000000, -32.000000)">
<g id="icon/banner/消息" transform="translate(1713.000000, 32.000000)">
<g id="编组">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M13.875,20.6585751 L13.9796526,20.6647179 C14.3523487,20.7094224 14.6,20.9943408 14.6,21.3949387 C14.6,21.793137 14.3546839,22.079785 13.9805499,22.1250542 L13.8720425,22.1313899 L10.125,22.1313023 L10.0203474,22.1251595 C9.64765132,22.080455 9.4,21.7955365 9.4,21.3949387 C9.4,20.9967404 9.64531608,20.7100924 10.0194501,20.6648232 L10.1279575,20.6584875 L13.875,20.6585751 Z M12,0.930991914 L12.114202,0.938656892 C12.4461465,0.982430206 12.6786924,1.21840343 12.7188472,1.56053658 L12.7250824,1.6705356 L12.724,2.83025932 L12.975759,2.90430031 L13.2244725,2.9413468 C16.687784,3.51732717 19.3536312,6.48703662 19.5838508,10.0724929 L19.5959741,10.3244915 L19.6000064,10.5775585 L19.6,18.0623023 L20.7499628,18.1131205 L20.8641749,18.1204751 C21.1961465,18.1642484 21.4286924,18.4002216 21.4688472,18.7423548 L21.4750824,18.8523538 L21.4678171,18.9675593 C21.4246486,19.3025982 21.1922705,19.5388574 20.8555499,19.5795997 L20.7470425,19.5859353 L3.25,19.5859353 L3.14534744,19.5797049 C2.77265132,19.5350005 2.525,19.250082 2.525,18.8494841 C2.525,18.4512975 2.77030543,18.1646386 3.1443756,18.1193685 L3.25285992,18.113033 L4.35003719,18.1123023 L4.4,10.5767569 L4.40403631,10.3246942 C4.524824,6.55675169 7.34298069,3.38911146 11.0266305,2.90405757 L11.229889,2.87995432 L11.275,1.66770897 L11.2823355,1.55103724 C11.3211556,1.24947788 11.5116242,1.02739927 11.7956288,0.955808301 L11.897531,0.937079811 L12,0.930991914 Z M12,4.31312051 C8.70150639,4.31312051 5.97362451,6.99932148 5.85407645,10.3480678 L5.85000794,10.5758657 L5.849,18.0622956 L18.099,18.1123023 L18.099,18.0619919 L18.1,17.9609919 L18.15,10.5767635 L18.1459233,10.3480647 C18.0266869,7.00812062 15.3071214,4.31312051 12,4.31312051 Z" id="形状结合" fill="#000000" fill-rule="nonzero"></path>
</g>
<circle id="Oval-1-Copy-2" fill="#F5222D" cx="18" cy="6" r="3"></circle>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-1713.000000, -32.000000)">
<g id="icon/banner/消息" transform="translate(1713.000000, 32.000000)">
<g id="编组">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M13.875,20.6585751 L13.9796526,20.6647179 C14.3523487,20.7094224 14.6,20.9943408 14.6,21.3949387 C14.6,21.793137 14.3546839,22.079785 13.9805499,22.1250542 L13.8720425,22.1313899 L10.125,22.1313023 L10.0203474,22.1251595 C9.64765132,22.080455 9.4,21.7955365 9.4,21.3949387 C9.4,20.9967404 9.64531608,20.7100924 10.0194501,20.6648232 L10.1279575,20.6584875 L13.875,20.6585751 Z M12,0.930991914 L12.114202,0.938656892 C12.4461465,0.982430206 12.6786924,1.21840343 12.7188472,1.56053658 L12.7250824,1.6705356 L12.724,2.83025932 L12.975759,2.90430031 L13.2244725,2.9413468 C16.687784,3.51732717 19.3536312,6.48703662 19.5838508,10.0724929 L19.5959741,10.3244915 L19.6000064,10.5775585 L19.6,18.0623023 L20.7499628,18.1131205 L20.8641749,18.1204751 C21.1961465,18.1642484 21.4286924,18.4002216 21.4688472,18.7423548 L21.4750824,18.8523538 L21.4678171,18.9675593 C21.4246486,19.3025982 21.1922705,19.5388574 20.8555499,19.5795997 L20.7470425,19.5859353 L3.25,19.5859353 L3.14534744,19.5797049 C2.77265132,19.5350005 2.525,19.250082 2.525,18.8494841 C2.525,18.4512975 2.77030543,18.1646386 3.1443756,18.1193685 L3.25285992,18.113033 L4.35003719,18.1123023 L4.4,10.5767569 L4.40403631,10.3246942 C4.524824,6.55675169 7.34298069,3.38911146 11.0266305,2.90405757 L11.229889,2.87995432 L11.275,1.66770897 L11.2823355,1.55103724 C11.3211556,1.24947788 11.5116242,1.02739927 11.7956288,0.955808301 L11.897531,0.937079811 L12,0.930991914 Z M12,4.31312051 C8.70150639,4.31312051 5.97362451,6.99932148 5.85407645,10.3480678 L5.85000794,10.5758657 L5.849,18.0622956 L18.099,18.1123023 L18.15,10.5767635 L18.1459233,10.3480647 C18.0266869,7.00812062 15.3071214,4.31312051 12,4.31312051 Z" id="形状结合" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
<circle id="Oval-1-Copy-2" fill="#F5222D" cx="18" cy="6" r="3"></circle>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-992.000000, -521.000000)">
<g id="设备告警" transform="translate(992.000000, 521.000000)">
<rect id="矩形" fill="#0B58FF" x="0" y="0" width="32" height="32" rx="16"></rect>
<g id="告警视图" transform="translate(8.196906, 8.196906)" fill-rule="nonzero">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="15.6061876" height="15.6061876"></rect>
<path d="M0,11.6800274 L0,1 C-1.78657678e-16,0.44771525 0.44771525,5.45542273e-16 1,0 L14.6061876,0 C15.1584723,-1.01453063e-16 15.6061876,0.44771525 15.6061876,1 L15.6061876,11.6800274 C15.6061876,12.2323122 15.1584723,12.6800274 14.6061876,12.6800274 L1,12.6800274 C0.44771525,12.6800274 -3.76453835e-16,12.2323122 0,11.6800274 Z M13.6554141,1.95077345 L1.95077345,1.95077345 L1.95077345,10.729254 L13.6554141,10.729254 L13.6554141,1.95077345 Z M7.80309379,6.82770706 C7.26440257,6.82770706 6.82770706,6.39101155 6.82770706,5.85232034 L6.82770706,3.90154689 C6.82770706,3.36285568 7.26440257,2.92616017 7.80309379,2.92616017 C8.341785,2.92616017 8.77848051,3.36285568 8.77848051,3.90154689 L8.77848051,5.85232034 C8.77848051,6.39101155 8.341785,6.82770706 7.80309379,6.82770706 Z M7.80309379,9.75386723 C7.26440257,9.75386723 6.82770706,9.31717172 6.82770706,8.77848051 C6.82770706,8.2397893 7.26440257,7.80309379 7.80309379,7.80309379 C8.341785,7.80309379 8.77848051,8.2397893 8.77848051,8.77848051 C8.77848051,9.31717172 8.341785,9.75386723 7.80309379,9.75386723 Z M11.7046407,15.6061876 L3.90154689,15.6061876 C3.36285568,15.6061876 2.92616017,15.1694921 2.92616017,14.6308009 C2.92616017,14.0921096 3.36285568,13.6554141 3.90154689,13.6554141 L11.7046407,13.6554141 C12.2433319,13.6554141 12.6800274,14.0921096 12.6800274,14.6308009 C12.6800274,15.1694921 12.2433319,15.6061876 11.7046407,15.6061876 Z" id="形状" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="56px" height="56px" viewBox="0 0 56 56" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-873.000000, -386.000000)">
<g id="设备管理" transform="translate(873.000000, 386.000000)">
<rect id="矩形备份-7" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="55" height="55"></rect>
<g id="编组-13" transform="translate(3.180289, 2.923263)">
<g id="编组-10" fill-rule="nonzero">
<g id="设备" fill="#0B58FF">
<rect id="矩形" opacity="0" x="2.00676053" y="1.65338444" width="46.1399529" height="46.1399529"></rect>
<g id="烧瓶,实验,化学,科学">
<rect id="矩形" opacity="0" x="4.42964393" y="4.42964393" width="41.294186" height="41.294186"></rect>
<g id="还原画布">
<rect id="矩形" opacity="0" x="0" y="0" width="50.1534739" height="50.1534739"></rect>
<path d="M1.72467326,45.9476439 C1.72467326,47.1152471 2.60037565,47.9909495 3.76797884,47.9909495 L46.3854951,47.9909495 C47.5530983,47.9909495 48.4288007,47.1152471 48.4288007,45.9476439 L48.4288007,13.8385563 L1.72467326,13.8385563 L1.72467326,45.9476439 Z M18.1370611,29.0173977 L38.650124,29.0173977 C39.6980043,29.0173977 40.5474792,29.8668726 40.5474792,30.9147529 C40.5474792,31.9626332 39.6980043,32.8121081 38.650124,32.8121081 L18.1370611,32.8121081 C17.0891807,32.8121081 16.2397059,31.9626332 16.2397059,30.9147529 C16.2397059,29.8668726 17.0891807,29.0173977 18.1370611,29.0173977 Z M10.2370348,36.6068184 L38.650124,36.6068184 C39.6980043,36.6068184 40.5474792,37.4562933 40.5474792,38.5041736 C40.5474792,39.5520539 39.6980043,40.4015288 38.650124,40.4015288 L10.2370348,40.4015288 C9.18915443,40.4015288 8.33967958,39.5520539 8.33967958,38.5041736 C8.33967958,37.4562933 9.18915443,36.6068184 10.2370348,36.6068184 Z M24.2010346,11.7952507 L1.72467326,11.7952507 L6.395086,3.62202844 C6.9788876,2.74632605 8.14649078,2.16252446 9.31409396,2.16252446 L23.9091338,2.16252446 L23.9091338,11.7952507 L24.2010346,11.7952507 Z M48.4288007,11.7952507 L26.2443401,11.7952507 L26.2443401,2.45442526 L40.8393799,2.45442526 C42.0069831,2.45442526 43.1745863,3.03822685 43.7583879,3.91392924 L48.4288007,11.7952507 Z" id="形状"></path>
</g>
</g>
</g>
<g id="还原画布" transform="translate(1.723618, 2.162524)" fill="#18104D">
<path d="M22.4763613,9.63272627 L0,9.63272627 L4.67041274,1.45950398 C5.25421433,0.583801592 6.42181752,0 7.5894207,0 L22.1844605,0 L22.1844605,9.63272627 L22.4763613,9.63272627 Z" id="形状"></path>
</g>
<g id="还原画布" transform="translate(26.191259, 2.454425)" fill="#18104D">
<path d="M22.1844605,9.34082548 L0,9.34082548 L0,0 L14.5950398,0 C15.762643,0 16.9302462,0.583801592 17.5140478,1.45950398 L22.1844605,9.34082548 Z" id="形状"></path>
</g>
</g>
<path d="M12.3066146,-5.29775726 L15.1753655,-3.62876956 C15.5740069,-3.25849694 15.8853072,-2.83209012 16.1092662,-2.34954908 C16.3332252,-1.86700804 16.4452047,-1.36084209 16.4452047,-0.831051217 L16.4452047,13.7613962 L12.3066146,13.7613962 L12.3066146,-5.29775726 Z" id="矩形" fill="#69F8AF" transform="translate(14.375910, 4.231819) rotate(-90.000000) translate(-14.375910, -4.231819) "></path>
<path d="M33.62186,-5.29775726 L36.4906108,-3.62876956 C36.8892523,-3.25849694 37.2005525,-2.83209012 37.4245115,-2.34954908 C37.6484705,-1.86700804 37.76045,-1.36084209 37.76045,-0.831051217 L37.76045,13.7613962 L33.62186,13.7613962 L33.62186,-5.29775726 Z" id="矩形备份-5" fill="#69F8AF" transform="translate(35.691155, 4.231819) scale(-1, 1) rotate(-90.000000) translate(-35.691155, -4.231819) "></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-992.000000, -164.000000)">
<g id="编组-8备份" transform="translate(968.000000, 140.000000)">
<g id="设备总览" transform="translate(24.000000, 24.000000)">
<rect id="矩形" fill="#0B58FF" x="0" y="0" width="32" height="32" rx="16"></rect>
<g id="烧瓶,实验,化学,科学" transform="translate(7.000000, 7.000000)" fill="#FFFFFF" fill-rule="nonzero">
<rect id="矩形" opacity="0" x="0.723623255" y="0.596198408" width="16.6377315" height="16.6377315"></rect>
<g>
<rect id="矩形" opacity="0" x="1.59729739" y="1.59729739" width="14.8903832" height="14.8903832"></rect>
<g id="还原画布">
<rect id="矩形" opacity="0" x="0" y="0" width="18.084978" height="18.084978"></rect>
<g id="玻璃" transform="translate(0.634017, 0.634017)">
<path d="M13.2593143,16.8169433 L0.5,16.8169433 C0.223857625,16.8169433 2.55862292e-16,16.5930857 0,16.3169433 L0,0.5 C-3.38176876e-17,0.223857625 0.223857625,1.61748834e-16 0.5,0 L13.2593143,0 C13.5354566,-5.07265313e-17 13.7593143,0.223857625 13.7593143,0.5 L13.7593143,16.3169433 C13.7593143,16.5930857 13.5354566,16.8169433 13.2593143,16.8169433 Z M1.37593143,15.2881288 L12.3833828,15.2881288 L12.3833828,1.52881452 L1.37593143,1.52881452 L1.37593143,15.2881288 Z M16.3169433,15.2881288 L13.4949152,15.2881288 C13.2187728,15.2881288 12.9949152,15.0642712 12.9949152,14.7881288 L12.9949152,2.02881452 C12.9949152,1.75267215 13.2187728,1.52881452 13.4949152,1.52881452 L16.3169433,1.52881452 C16.5930857,1.52881452 16.8169433,1.75267215 16.8169433,2.02881452 L16.8169433,14.7881288 C16.8169433,15.0642712 16.5930857,15.2881288 16.3169433,15.2881288 Z M3.2320096,9.37531556 C2.97585886,9.13419414 2.9636752,8.7310754 3.20479662,8.47492467 C3.20919378,8.47025343 3.21366127,8.46564888 3.21819754,8.46111261 L9.1694159,2.50989424 C9.42803493,2.25127521 9.84535293,2.24497024 10.1116667,2.49565843 C10.3678175,2.73677985 10.3800011,3.13989859 10.1388797,3.39604932 C10.1344826,3.40072056 10.1300151,3.40532511 10.1254788,3.40986138 L4.17426043,9.36107975 C3.9156414,9.61969878 3.4983234,9.62600375 3.2320096,9.37531556 Z M4.03073192,13.7322196 C3.77458118,13.4910982 3.76239752,13.0879795 4.00351894,12.8318287 C4.00791611,12.8271575 4.01238359,12.8225529 4.01691986,12.8180167 L9.96813823,6.86679831 C10.2267573,6.60817928 10.6440753,6.60187431 10.9103891,6.85256249 C11.1665398,7.09368392 11.1787235,7.49680265 10.937602,7.75295339 C10.9332049,7.75762463 10.9287374,7.76222918 10.9242011,7.76676545 L4.97298275,13.7179838 C4.71436372,13.9766028 4.29704572,13.9829078 4.03073192,13.7322196 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="56px" height="56px" viewBox="0 0 56 56" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-506.000000, -386.000000)">
<g id="订单管理" transform="translate(506.000000, 386.000000)">
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="55" height="55"></rect>
<g id="订单" transform="translate(0.499522, 1.000000)" fill-rule="nonzero">
<path d="M29.5269045,4.05189545 C43.5955288,4.05189545 55.0009567,15.4573234 55.0009567,29.5259477 C55.0009567,43.594572 43.5955288,55 29.5269045,55 C15.4582801,55 4.05285219,43.594572 4.05285219,29.5259477 C4.05285219,15.4573234 15.4582801,4.05189545 29.5269045,4.05189545 L29.5269045,4.05189545 Z M29.5269045,9.84145279 C18.6552737,9.84145279 9.84240952,18.654317 9.84240952,29.5259477 C9.84240952,40.3975785 18.6552737,49.2104427 29.5269045,49.2104427 C40.3985352,49.2104427 49.2113994,40.3975785 49.2113994,29.5259477 C49.2113994,18.654317 40.3985352,9.84145279 29.5269045,9.84145279 Z M29.5269045,13.3151872 C38.4798759,13.3151872 45.737665,20.5729763 45.737665,29.5259477 C45.737665,38.4789192 38.4798759,45.7367083 29.5269045,45.7367083 C20.573933,45.7367083 13.3161439,38.4789192 13.3161439,29.5259477 C13.3161439,20.5729763 20.573933,13.3151872 29.5269045,13.3151872 Z" id="形状" fill="#0B58FF"></path>
<path d="M29.5269045,17.9468331 C35.9220495,17.9468331 41.1060191,23.1308027 41.1060191,29.5259477 C41.1060191,35.9210928 35.9220495,41.1050624 29.5269045,41.1050624 C23.1317594,41.1050624 17.9477898,35.9210928 17.9477898,29.5259477 C17.9477898,23.1308027 23.1317594,17.9468331 29.5269045,17.9468331 Z M29.5269045,21.4205675 C25.0504265,21.4205675 21.4215242,25.0494698 21.4215242,29.5259477 C21.4215242,34.0024256 25.0504265,37.631328 29.5269045,37.631328 C34.0033824,37.631328 37.6322847,34.0024256 37.6322847,29.5259477 C37.6322847,25.0494698 34.0033824,21.4205675 29.5269045,21.4205675 Z" id="形状" fill="#69F8AF"></path>
<path d="M26.0531701,29.5259477 C26.0531701,30.7669935 26.7152601,31.9137671 27.7900372,32.53429 C28.8648144,33.154813 30.1889945,33.154813 31.2637717,32.53429 C32.3385489,31.9137671 33.0006389,30.7669935 33.0006389,29.5259477 C33.0006389,27.6074572 31.445395,26.0522133 29.5269045,26.0522133 C27.6084139,26.0522133 26.0531701,27.6074572 26.0531701,29.5259477 L26.0531701,29.5259477 Z" id="路径" fill="#69F8AF"></path>
<path d="M5.16097346,0.068680005 L11.4032742,6.31213864 C11.5452724,6.45390019 11.6069803,6.65727562 11.5676976,6.8540412 L10.9864261,9.75692525 L30.1405975,28.9122546 C30.4594387,29.2544288 30.4500307,29.787647 30.1193172,30.1183605 C29.7886037,30.449074 29.2553855,30.458482 28.9132114,30.1396408 L9.75788199,10.9854693 L6.85499794,11.5667409 C6.65823235,11.6060236 6.45485693,11.5443156 6.31309537,11.4023174 L0.070794654,5.16001673 C0.00785917816,5.09751387 -0.0154139259,5.00536463 0.010295925,4.92047361 C0.036005776,4.8355826 0.10649489,4.77182992 0.19353327,4.75474771 L3.60358254,4.07273786 C3.84074434,4.02516282 4.02611955,3.8397876 4.0736946,3.6026258 L4.75686236,0.192576532 C4.77415833,0.106307273 4.83733049,0.0364492466 4.92143088,0.0105907928 C5.00553127,-0.015267661 5.0970389,0.00703077709 5.15981555,0.068680005 L5.16097346,0.068680005 Z" id="路径" fill="#18104D"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-64.000000, -521.000000)">
<g id="工单监控" transform="translate(64.000000, 521.000000)">
<g id="监控" transform="translate(0.000000, 0.000000)" fill="#000000" fill-rule="nonzero" opacity="0">
<rect id="矩形" x="0" y="0" width="32" height="32"></rect>
</g>
<rect id="矩形" fill="#0B58FF" x="0" y="0" width="32" height="32" rx="16"></rect>
<path d="M7.95196014,15.04804 C7.95196014,17.9233277 9.4859078,20.5802032 11.97598,22.0178471 C14.4660522,23.455491 17.5339478,23.455491 20.02402,22.0178471 C22.5140922,20.5802032 24.0480399,17.9233277 24.0480399,15.04804 C24.0480399,12.1727522 22.5140922,9.51587679 20.02402,8.07823291 C17.5339477,6.64058903 14.4660523,6.64058903 11.97598,8.07823291 C9.48590782,9.51587679 7.95196014,12.1727522 7.95196014,15.04804 L7.95196014,15.04804 Z" id="路径" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M10.5399801,15.04804 C10.5399801,18.0635257 12.9845143,20.5080599 16,20.5080599 C19.0154857,20.5080599 21.4600199,18.0635257 21.4600199,15.04804 C21.4600199,12.0325543 19.0154857,9.58802008 16,9.58802008 C12.9845143,9.58802008 10.5399801,12.0325543 10.5399801,15.04804 L10.5399801,15.04804 Z" id="路径" fill="#0B58FF" fill-rule="nonzero"></path>
<path d="M13.12154,13.60882 C13.12154,14.4036848 13.7659053,15.04805 14.56077,15.04805 C15.3556348,15.04805 16,14.4036848 16,13.60882 C16,12.8139552 15.3556348,12.16959 14.56077,12.16959 C13.7659053,12.16959 13.12154,12.8139552 13.12154,13.60882 Z" id="路径" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M11.4822601,22.9347398 L10.8368601,22.9347398 L10.1914601,24.9999998 L21.8085399,24.9999998 L21.1631399,22.9347398 L20.5177399,22.9347398 C17.7631022,24.6949766 14.2368978,24.6949766 11.4822601,22.9347398 L11.4822601,22.9347398 Z" id="路径" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-64.000000, -164.000000)">
<g id="编组-8" transform="translate(40.000000, 140.000000)">
<g id="生产总览" transform="translate(24.000000, 24.000000)">
<rect id="矩形" fill="#0B58FF" x="0" y="0" width="32" height="32" rx="16"></rect>
<path d="M8.37437968,12.8114326 L15.7504058,17.0898781 C15.8242411,17.1328167 15.9080324,17.1555207 15.9933456,17.1555207 C16.0810002,17.1555207 16.1670458,17.131811 16.2414377,17.0872002 L23.5609995,12.8417393 C23.7926594,12.7069596 23.8719923,12.4078775 23.7377553,12.1750584 C23.6941637,12.0993735 23.6311005,12.036866 23.5563023,11.9947862 L16.2647451,7.74687591 C16.1909326,7.70388503 16.1071411,7.68113461 16.0218216,7.68113461 C15.9265067,7.68101965 15.8332679,7.70910321 15.7537378,7.76188227 L8.44005972,12.0039794 C8.20831857,12.137714 8.12809173,12.4360124 8.26123967,12.6689293 C8.29129448,12.7215224 8.33087471,12.7680046 8.37793917,12.8059787 L8.37437968,12.8114326 Z M21.6810442,15.0685273 L21.2137792,15.3395552 L21.2137792,15.3395552 L16.4927009,18.0091478 C16.1870188,18.1819995 15.8130711,18.1818429 15.5075339,18.0087351 L10.3178102,15.0684002 C10.0088558,14.8933563 9.63024672,14.895282 9.32308895,15.0734597 L8.44007598,15.5856824 L8.44007598,15.5856824 C8.20833482,15.719417 8.12807547,16.017699 8.26125592,16.2505344 C8.29182536,16.3040667 8.33225083,16.351269 8.38037719,16.3896249 L8.37728903,16.3948175 L15.7504708,20.6715484 C15.9025556,20.7600033 16.0903428,20.7590041 16.2414864,20.6689358 L23.5609995,16.4234259 C23.7926756,16.2885809 23.8720085,15.9895315 23.7377716,15.7567777 C23.6940662,15.6810601 23.6310842,15.61852 23.556286,15.5764238 L22.6861859,15.0694958 C22.3756549,14.8885777 21.9919233,14.8882079 21.6810442,15.0685273 Z M21.6866857,18.6534468 L21.2195166,18.924426 L21.2195166,18.924426 L16.4950848,21.6207262 C16.1882146,21.7958614 15.8117014,21.7960578 15.5046487,21.6212428 L10.7829566,18.9330314 L10.7829566,18.9330314 L10.3151216,18.661704 C10.0048329,18.4817477 9.6219281,18.4817646 9.31165532,18.6617485 L8.44007598,19.1673364 L8.44007598,19.1673364 C8.20833482,19.3010546 8.12810798,19.5993693 8.26125592,19.8322047 C8.29148444,19.8851411 8.33137304,19.9318794 8.37883311,19.9699725 L8.37546865,19.9753448 L15.7504221,24.2531371 C15.8242543,24.2960928 15.9080429,24.3187608 15.9933618,24.3188656 C16.0806614,24.3189335 16.1663657,24.2953601 16.2414539,24.2506225 L23.5610157,20.0050799 C23.7926756,19.8702023 23.8720085,19.5710875 23.7377716,19.3384318 C23.6941799,19.2627141 23.6311817,19.2001577 23.5563023,19.1580778 L22.6918543,18.6544197 C22.3813173,18.4734898 21.9975724,18.4731184 21.6866857,18.6534468 Z" id="形状" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="56px" height="56px" viewBox="0 0 56 56" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-1240.000000, -386.000000)">
<g id="质量管理" transform="translate(1240.000000, 386.000000)">
<rect id="矩形备份-10" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="55" height="55"></rect>
<g id="08质量" transform="translate(3.882568, 2.468968)">
<g id="编组-14" transform="translate(0.000000, 0.000000)">
<path d="M48.2348648,9.32705134 L48.2348648,23.3176283 C48.2348648,36.256626 39.5936261,48.3269278 28.0262536,51.2987824 C16.4131602,48.3726486 7.7719215,36.256626 7.7719215,23.3176283 L7.7719215,9.32705134 L28.0262536,0 L48.2348648,9.32705134 Z" id="路径" fill="#18104D" fill-rule="nonzero"></path>
<path d="M40.4629433,9.32705134 L40.4629433,23.3176283 C40.4629433,36.256626 31.8217046,48.3269278 20.2543321,51.2987824 C8.64123874,48.3726486 0,36.256626 0,23.3176283 L0,9.32705134 L20.2543321,0 L40.4629433,9.32705134 Z" id="形状" fill="#0B58FF" fill-rule="nonzero"></path>
<path d="M16.4804726,44.8381311 L23.9367499,44.8381311 C23.7967766,45.6009048 23.3406372,46.4633989 22.5683316,47.4256133 C21.4098731,48.8689349 20.2086112,49.4830135 20.2086112,49.4830135 C20.2086112,49.4830135 18.8612116,48.5451406 17.9626413,47.4256133 C17.3635945,46.6792617 16.8695382,45.8167676 16.4804726,44.8381311 Z" id="路径-2" fill="#69F8AF"></path>
<path d="M20.2086112,14.5392271 C26.2894829,14.5392271 31.1816128,19.431357 31.1816128,25.5122287 C31.1816128,28.84985 29.6728251,31.8217046 27.3410623,33.8334215 L28.7355479,35.2279071 C29.4551992,35.9475584 29.4551992,37.1143437 28.7355479,37.833995 C28.0158966,38.5536463 26.8491113,38.5536463 26.12946,37.833995 L24.0948826,35.7994176 C22.8604199,36.2109052 21.5802364,36.4852302 20.2086112,36.4852302 C14.1277395,36.4852302 9.23560966,31.5473795 9.23560966,25.5122287 C9.23560966,19.4770778 14.1277395,14.5392271 20.2086112,14.5392271 Z M20.2086112,18.1968943 C16.1851773,18.1968943 12.8932768,21.4887947 12.8932768,25.5122287 C12.8932768,29.5356626 16.1851773,32.827563 20.2086112,32.827563 C20.4829363,32.827563 20.8029821,32.827563 21.0773072,32.7818422 L20.9630051,32.6675401 C20.2433538,31.9478888 20.2433538,30.7811035 20.9630051,30.0614522 C21.6826564,29.3418009 22.8494417,29.3418009 23.569093,30.0614522 L24.7349744,31.2273336 C26.4266455,29.9014293 27.5239456,27.8439915 27.5239456,25.5122287 C27.5239456,21.4887947 24.2320451,18.1968943 20.2086112,18.1968943 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="56px" height="56px" viewBox="0 0 56 56" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="主界面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="主页" transform="translate(-1607.000000, -386.000000)">
<g id="仓库管理" transform="translate(1607.000000, 386.000000)">
<rect id="矩形备份-11" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="55" height="55"></rect>
<g id="编组" transform="translate(4.828118, 3.724695)" fill-rule="nonzero">
<path d="M46.3437634,22.1260999 C46.3437634,20.5189711 45.6536539,18.9916368 44.4577566,17.9509367 L24.3260872,0.434356738 C23.6604711,-0.144785579 22.6832923,-0.144785579 22.0176762,0.434356738 L1.88600685,17.9509367 C0.689748793,18.9917824 0,20.5183296 0,22.1260999 L0,31.9992652 L23.1718817,30.7180576 L46.3437634,31.9992652 L46.3437634,22.1260999 Z" id="路径" fill="#18104D"></path>
<path d="M24.3260873,10.3527476 L46.3437634,28.9647616 L46.3437634,46.7765289 C46.3437634,47.7558213 45.5461328,48.5506093 44.560889,48.5506093 L29.4914859,48.5506093 L29.4914859,38.0698881 C29.4914859,34.5968826 26.6621028,31.7814554 23.1718819,31.7814554 C19.6816609,31.7814554 16.8522778,34.5968826 16.8522778,38.0698881 L16.8522778,48.5506093 L1.78287475,48.5506093 C1.3098369,48.5506093 0.856189467,48.363548 0.521804101,48.0306072 C0.187418735,47.6976665 0,47.2461416 0,46.7754371 L0,28.9636698 L22.0176764,10.3527476 C22.6832925,9.7901594 23.6604713,9.7901594 24.3260873,10.3527476 Z" id="路径" fill="#0B58FF"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title></title>
<g id="页面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="栏" transform="translate(-383.000000, -639.000000)" fill="#FFFFFF" fill-rule="nonzero">
<g id="制度流程" transform="translate(383.000000, 639.000000)">
<rect id="矩形" opacity="0" x="0" y="0" width="24" height="24"></rect>
<path d="M4.37117174,17.071929 L2.37885068,17.071929 C2.0028361,17.071929 1.69692899,17.3771995 1.69692899,17.7524526 L1.69692899,19.7475474 C1.69692899,20.1227781 2.00283612,20.428071 2.37885068,20.428071 L4.37117174,20.428071 C4.74718632,20.428071 5.05307101,20.1228005 5.05307101,19.7475474 L5.05307101,17.7524526 C5.05307101,17.3771996 4.74718632,17.071929 4.37117174,17.071929 Z M7.36536289,6.40073051 L21.8846371,6.40073051 C22.2245029,6.40073051 22.5,6.06492662 22.5,5.65073051 C22.5,5.2365344 22.2245029,4.90073051 21.8846371,4.90073051 L7.36536289,4.90073051 C7.02549709,4.90073051 6.75,5.23653442 6.75,5.65073054 C6.75,6.06492665 7.02549711,6.40073051 7.36536289,6.40073051 Z M3.14077284,5.95492436 L2.03265569,4.84248673 C1.8767502,4.68597337 1.62348469,4.6854806 1.46697133,4.84138609 C1.4665023,4.8418533 1.46603442,4.84232168 1.46556772,4.84279121 L1.18448184,5.12557972 C1.0295067,5.28149361 1.02939503,5.5332514 1.1842318,5.6893027 L2.85590574,7.37408916 C3.01150401,7.53090793 3.26476807,7.53189735 3.42158685,7.37629907 C3.42263304,7.37526103 3.42367349,7.3742172 3.42470814,7.37316765 L5.7220224,5.04277966 C5.87599957,4.88658572 5.87547971,4.63552909 5.72085699,4.47997417 L5.4403523,4.19777835 C5.28461275,4.04109986 5.0313479,4.04033871 4.87466942,4.19607825 C4.87370895,4.19703297 4.87275333,4.19799256 4.8718026,4.19895698 L3.14077284,5.95492436 L3.14077284,5.95492436 Z M21.8846371,11.25 L7.36536289,11.25 C7.02549709,11.25 6.75,11.5857972 6.75,11.999985 C6.75,12.4141729 7.02552167,12.75 7.36536289,12.75 L21.8846371,12.75 C22.2245029,12.75 22.5,12.4142028 22.5,11.999985 C22.5,11.5857672 22.2245029,11.25 21.8846371,11.25 Z M21.8846371,17.972656 L7.36536289,17.972656 C7.02549709,17.972656 6.75,18.30843 6.75,18.722656 C6.75,19.1368821 7.02552167,19.472656 7.36536289,19.472656 L21.8846371,19.472656 C22.2245029,19.472656 22.5,19.1368821 22.5,18.722656 C22.5,18.30843 22.2245029,17.972656 21.8846371,17.972656 Z M4.37117174,10.321929 L2.37885068,10.321929 C2.0028361,10.321929 1.69692899,10.6271975 1.69692899,11.0024481 L1.69692899,12.9975519 C1.69692899,13.3727801 2.00283612,13.678071 2.37885068,13.678071 L4.37117174,13.678071 C4.74718632,13.678071 5.05307101,13.3728025 5.05307101,12.9975519 L5.05307101,11.0024481 C5.05307101,10.6271975 4.74718632,10.321929 4.37117174,10.321929 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
src/assets/img/alarm-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
src/assets/img/home-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

View File

@ -80,7 +80,7 @@
.submenu-title-noDropdown, .submenu-title-noDropdown,
.el-submenu__title { .el-submenu__title {
&:hover { &:hover {
background-color: rgba(0, 0, 0, 0.06) !important; background-color: #0b58ff !important;
} }
} }

View File

@ -37,18 +37,18 @@ $base-sub-menu-hover:#001528;
*/ */
$base-menu-color: #fff; $base-menu-color: #fff;
$base-menu-color-active:#fff; $base-menu-color-active:#fff;
$base-menu-background:#001529; $base-menu-background:#1E1651;
$base-logo-title-color: #ffffff; $base-logo-title-color: #ffffff;
$base-menu-light-color:rgba(0,0,0,.70); $base-menu-light-color:rgba(0,0,0,.70);
$base-menu-light-background:#ffffff; $base-menu-light-background:#ffffff;
$base-logo-light-title-color: #001529; $base-logo-light-title-color: #001529;
$base-sub-menu-background:#0B253F; $base-sub-menu-background:#15063C;
$base-sub-menu-hover:#0b50ff; $base-sub-menu-hover:#0b50ff;
$base-sidebar-width: 248px; $base-sidebar-width: 282px;
// the :export directive is the magic sauce for webpack // the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass

View File

@ -2,26 +2,39 @@
<el-menu <el-menu
:default-active="activeMenu" :default-active="activeMenu"
mode="horizontal" mode="horizontal"
@select="handleSelect" @select="handleSelect">
>
<template v-for="(item, index) in topMenus"> <template v-for="(item, index) in topMenus">
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"> <el-menu-item
<svg-icon :icon-class="item.meta.icon"/> :style="{ '--theme': theme }"
:index="item.path"
:key="index"
v-if="index < visibleNumber">
<!-- <svg-icon :icon-class="item.meta.icon" /> -->
<span class="menu-box" :class="{ active: item.path === currentIndex }">
<span class="menu-dot"></span>
{{ item.meta.title }} {{ item.meta.title }}
</span>
</el-menu-item> </el-menu-item>
</template> </template>
<!-- 顶部菜单超出数量折叠 --> <!-- 顶部菜单超出数量折叠 -->
<el-submenu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> <el-submenu
:style="{ '--theme': theme }"
index="more"
v-if="topMenus.length > visibleNumber">
<template slot="title">更多菜单</template> <template slot="title">更多菜单</template>
<template v-for="(item, index) in topMenus"> <template v-for="(item, index) in topMenus">
<el-menu-item <el-menu-item
:index="item.path" :index="item.path"
:key="index" :key="index"
v-if="index >= visibleNumber" v-if="index >= visibleNumber">
> <!-- <svg-icon :icon-class="item.meta.icon" /> -->
<svg-icon :icon-class="item.meta.icon"/> <span
class="menu-box"
:class="{ active: item.path === currentIndex }">
<span class="menu-dot"></span>
{{ item.meta.title }} {{ item.meta.title }}
</span>
</el-menu-item> </el-menu-item>
</template> </template>
</el-submenu> </el-submenu>
@ -29,7 +42,8 @@
</template> </template>
<script> <script>
import { constantRoutes } from "@/router"; import { mapGetters } from 'vuex';
import { constantRoutes } from '@/router';
// //
const hideList = ['/index', '/user/profile']; const hideList = ['/index', '/user/profile'];
@ -39,11 +53,13 @@ export default {
return { return {
// //
visibleNumber: 5, visibleNumber: 5,
// index
currentIndex: undefined
}; };
}, },
computed: { computed: {
...mapGetters(['choicepart']),
currentIndex() {
return this.choicepart;
},
theme() { theme() {
return this.$store.state.settings.theme; return this.$store.state.settings.theme;
}, },
@ -53,13 +69,14 @@ export default {
this.routers.map((menu) => { this.routers.map((menu) => {
if (menu.hidden !== true) { if (menu.hidden !== true) {
// //
if (menu.path === "/") { if (menu.path === '/') {
topMenus.push(menu.children[0]); topMenus.push(menu.children[0]);
} else { } else {
topMenus.push(menu); topMenus.push(menu);
} }
} }
}); });
console.log('topMenus:', topMenus);
return topMenus; return topMenus;
}, },
// //
@ -72,11 +89,12 @@ export default {
this.routers.map((router) => { this.routers.map((router) => {
for (let item in router.children) { for (let item in router.children) {
if (router.children[item].parentPath === undefined) { if (router.children[item].parentPath === undefined) {
if(router.path === "/") { if (router.path === '/') {
router.children[item].path = "/" + router.children[item].path; router.children[item].path = '/' + router.children[item].path;
} else { } else {
if(!this.ishttp(router.children[item].path)) { if (!this.ishttp(router.children[item].path)) {
router.children[item].path = router.path + "/" + router.children[item].path; router.children[item].path =
router.path + '/' + router.children[item].path;
} }
} }
router.children[item].parentPath = router.path; router.children[item].parentPath = router.path;
@ -90,13 +108,17 @@ export default {
activeMenu() { activeMenu() {
const path = this.$route.path; const path = this.$route.path;
let activePath = path; let activePath = path;
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) { if (
path !== undefined &&
path.lastIndexOf('/') > 0 &&
hideList.indexOf(path) === -1
) {
const tmpPath = path.substring(1, path.length); const tmpPath = path.substring(1, path.length);
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")); activePath = '/' + tmpPath.substring(0, tmpPath.indexOf('/'));
if (!this.$route.meta.link) { if (!this.$route.meta.link) {
this.$store.dispatch('app/toggleSideBarHide', false) this.$store.dispatch('app/toggleSideBarHide', false);
} }
} else if(!this.$route.children) { } else if (!this.$route.children) {
activePath = path; activePath = path;
this.$store.dispatch('app/toggleSideBarHide', true); this.$store.dispatch('app/toggleSideBarHide', true);
} }
@ -105,10 +127,10 @@ export default {
}, },
}, },
beforeMount() { beforeMount() {
window.addEventListener('resize', this.setVisibleNumber) window.addEventListener('resize', this.setVisibleNumber);
}, },
beforeDestroy() { beforeDestroy() {
window.removeEventListener('resize', this.setVisibleNumber) window.removeEventListener('resize', this.setVisibleNumber);
}, },
mounted() { mounted() {
this.setVisibleNumber(); this.setVisibleNumber();
@ -116,62 +138,93 @@ export default {
methods: { methods: {
// //
setVisibleNumber() { setVisibleNumber() {
const width = document.body.getBoundingClientRect().width / 3; const width = window.innerWidth - 700;
this.visibleNumber = parseInt(width / 85); console.log(width);
console.log('window.innerWidth:', window.innerWidth);
this.visibleNumber = parseInt(width / 120);
console.log('this.visibleNumber:', this.visibleNumber);
}, },
// //
handleSelect(key, keyPath) { handleSelect(key, keyPath) {
this.currentIndex = key; // this.currentIndex = key;
const route = this.routers.find(item => item.path === key); const route = this.routers.find((item) => item.path === key);
if (this.ishttp(key)) { console.log('route:', route);
// http(s):// this.$store.dispatch('app/setChoicepart', key);
window.open(key, "_blank"); this.toRouter(route);
} else if (!route || !route.children) { // if (this.ishttp(key)) {
// // // http(s)://
this.$router.push({ path: key }); // window.open(key, '_blank');
this.$store.dispatch('app/toggleSideBarHide', true); // console.log('aaaaaaaaaaaaaa');
// } else if (!route || !route.children) {
// //
// this.$router.push({ path: key });
// this.$store.dispatch('app/toggleSideBarHide', true);
// console.log('bbbbbbbbbbbbbbb');
// } else {
// //
// this.activeRoutes(key);
// if (!this.$route.meta.link) {
// this.$store.dispatch('app/toggleSideBarHide', false);
// }
// console.log('cccccccccccccccc');
// }
},
toRouter(item) {
console.log(item);
if (item.children) {
this.toRouter(item.children[0]);
} else { } else {
// this.$router.push({ name: item.name });
this.activeRoutes(key);
if (!this.$route.meta.link) {
this.$store.dispatch('app/toggleSideBarHide', false);
}
} }
}, },
// //
activeRoutes(key) { activeRoutes(key) {
const routes = [] this.$store.dispatch('app/setChoicepart', key);
const routes = [];
if (this.childrenMenus && this.childrenMenus.length > 0) { if (this.childrenMenus && this.childrenMenus.length > 0) {
this.childrenMenus.map((item) => { this.childrenMenus.map((item) => {
if (key === item.parentPath || (key === "index" && "" === item.path)) { if (
key === item.parentPath ||
(key === 'index' && '' === item.path)
) {
routes.push(item); routes.push(item);
} }
}); });
} }
if(routes.length > 0) { if (routes.length > 0) {
this.$store.commit("SET_SIDEBAR_ROUTERS", routes); this.$store.commit('SET_SIDEBAR_ROUTERS', routes);
} else { } else {
this.$store.dispatch('app/toggleSideBarHide', true); this.$store.dispatch('app/toggleSideBarHide', true);
} }
}, },
ishttp(url) { ishttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
} },
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.topmenu-container.el-menu.el-menu--horizontal {
border-bottom: none;
}
.topmenu-container.el-menu.el-menu--horizontal > .el-menu-item.is-active {
border-bottom: none !important;
}
.topmenu-container.el-menu.el-menu--horizontal > .el-submenu.is-active {
--theme: none !important;
}
.topmenu-container.el-menu--horizontal > .el-menu-item { .topmenu-container.el-menu--horizontal > .el-menu-item {
float: left; float: left;
height: 50px !important; height: 84px !important;
line-height: 50px !important; line-height: 84px !important;
color: #999093 !important; color: transparent !important;
padding: 0 5px !important; padding: 0 5px !important;
margin: 0 10px !important; font-size: 18px;
} }
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title { .topmenu-container.el-menu--horizontal > .el-menu-item.is-active,
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important; border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133; color: #303133;
} }
@ -179,10 +232,34 @@ export default {
/* submenu item */ /* submenu item */
.topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title { .topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
float: left; float: left;
height: 50px !important; height: 84px !important;
line-height: 50px !important; line-height: 89px !important;
color: #999093 !important; color: #000 !important;
padding: 0 5px !important; padding: 0 5px !important;
margin: 0 10px !important; margin: 0 10px !important;
font-size: 18px;
}
</style>
<style lang="scss" scoped>
.menu-box {
padding: 7px 15px 9px 15px;
border-radius: 32px;
color: #000;
}
.active {
background: #dce7ff;
.menu-dot {
opacity: 1;
}
}
.menu-dot {
display: inline-block;
width: 5px;
height: 5px;
border-radius: 50%;
background: #0b58ff;
margin-right: 3px;
margin-bottom: 2px;
opacity: 0;
} }
</style> </style>

View File

@ -10,26 +10,26 @@
</template> </template>
<script> <script>
import iframeToggle from "./IframeToggle/index" import iframeToggle from './IframeToggle/index';
export default { export default {
name: 'AppMain', name: 'AppMain',
components: { iframeToggle }, components: { iframeToggle },
computed: { computed: {
cachedViews() { cachedViews() {
return this.$store.state.tagsView.cachedViews return this.$store.state.tagsView.cachedViews;
}, },
key() { key() {
return this.$route.path return this.$route.path;
} },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.app-main { .app-main {
/* 48= navbar 48 */ /* 48= navbar 48 */
min-height: calc(100vh - 56px); // min-height: calc(100vh - 84px);
min-width: calc(100vh - 280px); min-width: calc(100vh - 280px);
position: relative; position: relative;
overflow: visible; overflow: visible;
@ -39,13 +39,13 @@ export default {
} }
.fixed-header + .app-main { .fixed-header + .app-main {
padding-top: 56px; padding-top: 84px;
} }
.hasTagsView { .hasTagsView {
.app-main { .app-main {
/* 84 = navbar + tags-view = 50 + 34 */ /* 84 = navbar + tags-view = 50 + 34 */
min-height: calc(100vh - 120px - 8px); min-height: calc(100vh - 164px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }

View File

@ -1,62 +1,34 @@
<template> <template>
<div class="navbar"> <div class="navbar">
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> <hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar" />
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/> <breadcrumb
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/> id="breadcrumb-container"
class="breadcrumb-container"
v-if="!topNav" />
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
<div style="padding-top: 5px; padding-right: 38px;"> <div style="padding-top: 5px; padding-right: 24px">
<navbar-right :blackTitle='true'/> <navbar-right :blackTitle="true" />
</div> </div>
<!-- <div class="right-menu"> -->
<!-- <template v-if="device!=='mobile'"> -->
<!-- <search id="header-search" class="right-menu-item" /> -->
<!-- 站内信 -->
<!-- <notify-message class="right-menu-item hover-effect" /> -->
<!-- <screenfull id="screenfull" class="right-menu-item hover-effect" /> -->
<!-- <el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip> -->
<!-- </template> -->
<!-- <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper"> -->
<!-- <img :src="avatar" class="user-avatar"> -->
<!-- <span v-if="nickname" class="user-nickname">{{ nickname }}</span>
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">
<router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link> -->
<!-- <el-dropdown-item @click.native="setting = true">
<span>布局设置</span>
</el-dropdown-item> -->
<!-- <el-dropdown-item divided @click.native="logout">
<span>退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown> -->
<!-- </div> -->
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
import Breadcrumb from '@/components/Breadcrumb' import Breadcrumb from '@/components/Breadcrumb';
import TopNav from '@/components/TopNav' import TopNav from '@/components/TopNav';
import Hamburger from '@/components/Hamburger' import Hamburger from '@/components/Hamburger';
import Screenfull from '@/components/Screenfull' import Screenfull from '@/components/Screenfull';
import SizeSelect from '@/components/SizeSelect' import SizeSelect from '@/components/SizeSelect';
import Search from '@/components/HeaderSearch' import Search from '@/components/HeaderSearch';
import NotifyMessage from '@/layout/components/Message' import NotifyMessage from '@/layout/components/Message';
// import {getPath} from "@/utils/ruoyi"; // import {getPath} from "@/utils/ruoyi";
import NavbarRight from './NavbarRight.vue' import NavbarRight from './NavbarRight.vue';
export default { export default {
components: { components: {
@ -67,65 +39,63 @@ export default {
SizeSelect, SizeSelect,
Search, Search,
NotifyMessage, NotifyMessage,
NavbarRight NavbarRight,
}, },
computed: { computed: {
...mapGetters([ ...mapGetters(['sidebar', 'avatar', 'nickname', 'device']),
'sidebar',
'avatar',
'nickname',
'device'
]),
setting: { setting: {
get() { get() {
return this.$store.state.settings.showSettings return this.$store.state.settings.showSettings;
}, },
set(val) { set(val) {
this.$store.dispatch('settings/changeSetting', { this.$store.dispatch('settings/changeSetting', {
key: 'showSettings', key: 'showSettings',
value: val value: val,
}) });
} },
}, },
topNav: { topNav: {
get() { get() {
return this.$store.state.settings.topNav return this.$store.state.settings.topNav;
} },
} },
}, },
methods: { methods: {
toggleSideBar() { toggleSideBar() {
this.$store.dispatch('app/toggleSideBar') this.$store.dispatch('app/toggleSideBar');
}, },
async logout() { async logout() {
this.$modal.confirm('确定注销并退出系统吗?', '提示').then(() => { this.$modal
.confirm('确定注销并退出系统吗?', '提示')
.then(() => {
this.$store.dispatch('LogOut').then(() => { this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/'); location.href = getPath('/');
});
}) })
}).catch(() => {}); .catch(() => {});
} },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.navbar { .navbar {
height: 48px; // 56 height: 84px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
background: #fff; background: #fff;
box-shadow: 0 1px 4px rgba(0,21,41,.08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container { .hamburger-container {
line-height: 52px; line-height: 84px;
height: 100%; height: 100%;
float: left; float: left;
cursor: pointer; cursor: pointer;
transition: background .3s; transition: background 0.3s;
-webkit-tap-highlight-color:transparent; -webkit-tap-highlight-color: transparent;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: rgba(0, 0, 0, 0.025);
} }
} }
@ -162,10 +132,10 @@ export default {
&.hover-effect { &.hover-effect {
cursor: pointer; cursor: pointer;
transition: background .3s; transition: background 0.3s;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: rgba(0, 0, 0, 0.025);
} }
} }
} }
@ -185,7 +155,7 @@ export default {
height: 35px; height: 35px;
border-radius: 50%; border-radius: 50%;
} }
.user-nickname{ .user-nickname {
margin-left: 5px; margin-left: 5px;
font-size: 14px; font-size: 14px;
} }

View File

@ -1,90 +1,111 @@
<template> <template>
<div class="right-msg" :style="blackTitle ? 'color: #000' : 'color: #fff'"> <div class="right-msg" :style="blackTitle ? 'color: #000' : 'color: #fff'">
<div class="home-icon" v-if='blackTitle'> <div class="home-icon" v-if="blackTitle">
<svg-icon icon-class="home" style="font-size: 24px; cursor: pointer;" @click="toHome"/> <!-- <svg-icon
icon-class="home"
style="font-size: 24px; cursor: pointer"
@click="toHome" /> -->
<svg-icon
icon-class="alarm"
style="font-size: 24px; cursor: pointer"
@click="toAlarm" />
</div> </div>
<div class="time-msg"> <!-- <div class="time-msg">
<div class="line1">{{timeZone}}&nbsp;&nbsp;&nbsp;&nbsp;{{topTime}}</div> <div class="line1">{{timeZone}}&nbsp;&nbsp;&nbsp;&nbsp;{{topTime}}</div>
<div class="line2">{{topDate}}</div> <div class="line2">{{topDate}}</div>
</div> </div> -->
<div class="base-msg"> <div class="base-msg">
<div class="avatar"> <div class="avatar">
<el-dropdown> <el-dropdown>
<img :src="require(`../../assets/images/choicepart/avatar.png`)" alt="" width="32" height="32" /> <img
:src="require(`../../assets/images/choicepart/avatar.png`)"
alt=""
width="42"
height="42"
style="position: relative; top: 4px" />
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item><svg-icon icon-class="helpbtn"/>帮助文档</el-dropdown-item> <!-- <el-dropdown-item>
<el-dropdown-item @click.native="logout"><svg-icon icon-class="exitbtn"/>退出登录</el-dropdown-item> <svg-icon icon-class="helpbtn" />
帮助文档
</el-dropdown-item> -->
<el-dropdown-item @click.native="logout">
<svg-icon icon-class="exitbtn" />
退出登录
</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</div> </div>
<div class="use-msg"> <div class="use-msg">
<div class="line1">{{nickname}}</div> <div class="line1">{{ nickname }}</div>
<div class="line2">{{dept}}</div> <div class="line2">{{ dept }}</div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import moment from 'moment' import moment from 'moment';
import { getUser } from "@/api/system/user.js"; import { getUser } from '@/api/system/user.js';
import {getPath} from "@/utils/ruoyi"; import { getPath } from '@/utils/ruoyi';
export default { export default {
name: 'navRight', name: 'navRight',
data() { data() {
return { return {
topDate: '', // topDate: '',
topTime: '', // topTime: '',
timeZone: '', // timeZone: '',
timer: '', timer: '',
dept:' ', dept: ' ',
nickname: this.$store.getters.nickname nickname: this.$store.getters.nickname,
} };
}, },
props: { props: {
blackTitle: { blackTitle: {
type: Boolean, type: Boolean,
default: () => { default: () => {
return false return false;
} },
} },
}, },
created() { created() {
this.getUserMsg() this.getUserMsg();
this.getTime() // this.getTime();
}, },
beforeDestroy() { beforeDestroy() {
clearInterval(this.timer) clearInterval(this.timer);
}, },
methods: { methods: {
getTime() { // getTime() {
let _this = this // let _this = this;
this.timer = setInterval(function () { // this.timer = setInterval(function () {
_this.topDate = moment().format('YYYY/MM/DD') // _this.topDate = moment().format('YYYY/MM/DD');
let temp = moment().format('A-hh:mm').split('-') // let temp = moment().format('A-hh:mm').split('-');
_this.timeZone = temp[0] // _this.timeZone = temp[0];
_this.topTime = temp[1] // _this.topTime = temp[1];
}, 1000) // }, 1000);
}, // },
getUserMsg() { getUserMsg() {
let id = this.$store.getters.userId let id = this.$store.getters.userId;
getUser(id).then(res => { getUser(id).then((res) => {
this.dept = res.data.dept ? res.data.dept.name : '' this.dept = res.data.dept ? res.data.dept.name : '';
}) });
}, },
async logout() { async logout() {
this.$modal.confirm('确定注销并退出系统吗?', '提示').then(() => { this.$modal
.confirm('确定注销并退出系统吗?', '提示')
.then(() => {
this.$store.dispatch('LogOut').then(() => { this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/'); location.href = getPath('/');
});
}) })
}).catch(() => {}) .catch(() => {});
}, },
toHome() { toAlarm() {
this.$router.push({ path: "/" }) this.$router.push({ path: '/abnormalWarning' });
} },
} },
} };
</script> </script>
<style lang='scss' scoped> <style lang="scss" scoped>
.right-msg { .right-msg {
float: right; float: right;
height: 100%; height: 100%;
@ -95,12 +116,13 @@ export default {
} }
.home-icon { .home-icon {
display: inline-block; display: inline-block;
margin-right: 30px; margin-right: 20px;
vertical-align: top; vertical-align: top;
padding-top: 7px; line-height: 84px;
} }
.base-msg { .base-msg {
display: inline-block; display: inline-block;
padding-top: 10px;
.avatar { .avatar {
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;

View File

@ -17,7 +17,9 @@ export default {
const vnodes = [] const vnodes = []
if (icon) { if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>) vnodes.push(<svg-icon style="font-size: 18px;margin-right: 10px;vertical-align: middle;" icon-class={icon}/>)
} else {
vnodes.push(<span style="display: inline-block; width: 10px;"/>)
} }
if (title) { if (title) {

View File

@ -4,7 +4,7 @@
:class="{ collapse: collapse }" :class="{ collapse: collapse }"
:style="{ :style="{
backgroundColor: backgroundColor:
sideTheme === 'theme-dark' ? '#1f2d3d' : variables.menuLightBackground, sideTheme === 'theme-dark' ? '#1E1651' : variables.menuLightBackground,
}"> }">
<!-- sideTheme === 'theme-dark' <!-- sideTheme === 'theme-dark'
? variables.menuBackground ? variables.menuBackground
@ -46,7 +46,7 @@
</template> </template>
<script> <script>
import logoImg from '@/assets/logo/logo.png'; import logoImg from '@/assets/logo/cnbm.png';
import variables from '@/assets/styles/variables.scss'; import variables from '@/assets/styles/variables.scss';
export default { export default {
@ -67,7 +67,7 @@ export default {
}, },
data() { data() {
return { return {
title: '中建材智能化院', title: 'MES产品化重构',
logo: logoImg, logo: logoImg,
}; };
}, },
@ -87,8 +87,8 @@ export default {
.sidebar-logo-container { .sidebar-logo-container {
position: relative; position: relative;
width: 100%; width: 100%;
height: 56px; height: 84px;
line-height: 56px; line-height: 84px;
background: #1445cc; background: #1445cc;
text-align: center; text-align: center;
overflow: hidden; overflow: hidden;
@ -98,20 +98,19 @@ export default {
width: 100%; width: 100%;
& .sidebar-logo { & .sidebar-logo {
width: 32px; width: 34px;
height: 40px; height: 34px;
vertical-align: middle; vertical-align: middle;
margin-right: 12px; margin-right: 8px;
} }
& .sidebar-title { & .sidebar-title {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
color: #fff; color: #fff;
font-weight: 600; font-weight: 500;
line-height: 50px; line-height: 50px;
font-size: 18px; font-size: 26px;
letter-spacing: 1px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle; vertical-align: middle;
} }

View File

@ -1,96 +0,0 @@
<template>
<div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</template>
<sidebar-item
v-for="(child, index) in item.children"
:key="child.path + index"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
export default {
name: 'SidebarItem',
components: { Item, AppLink },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
this.onlyOneChild = null
return {}
},
methods: {
hasOneShowingChild(children = [], parent) {
if (!children) {
children = [];
}
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
}
}
</script>

View File

@ -1,96 +1,107 @@
<template> <template>
<div v-if="!item.hidden"> <div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> <template
v-if="
hasOneShowingChild(item.children, item) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.alwaysShow
">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> <el-menu-item
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> :index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }">
<item icon="menuIcon" :title="onlyOneChild.meta.title" />
</el-menu-item> </el-menu-item>
</app-link> </app-link>
</template> </template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> <el-submenu
v-else
ref="subMenu"
:index="resolvePath(item.path)"
popper-append-to-body>
<template slot="title"> <template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> <item v-if="item.meta" icon="menuIcon" :title="item.meta.title" />
</template> </template>
<sidebar-item <sidebar-item-sub
v-for="(child, index) in item.children" v-for="(child, index) in item.children"
:key="child.path + index" :key="child.path + index"
:is-nest="true" :is-nest="true"
:item="child" :item="child"
:base-path="resolvePath(child.path)" :base-path="resolvePath(child.path)"
class="nest-menu" class="nest-menu" />
/>
</el-submenu> </el-submenu>
</div> </div>
</template> </template>
<script> <script>
import path from 'path' import path from 'path';
import { isExternal } from '@/utils/validate' import { isExternal } from '@/utils/validate';
import Item from './Item' import Item from './Item';
import AppLink from './Link' import AppLink from './Link';
import FixiOSBug from './FixiOSBug' import FixiOSBug from './FixiOSBug';
import SidebarItemSub from './SidebarItemSub';
export default { export default {
name: 'SidebarItem', name: 'SidebarItem',
components: { Item, AppLink }, components: { Item, AppLink, SidebarItemSub },
mixins: [FixiOSBug], mixins: [FixiOSBug],
props: { props: {
// route object // route object
item: { item: {
type: Object, type: Object,
required: true required: true,
}, },
isNest: { isNest: {
type: Boolean, type: Boolean,
default: false default: false,
}, },
basePath: { basePath: {
type: String, type: String,
default: '' default: '',
} },
}, },
data() { data() {
this.onlyOneChild = null this.onlyOneChild = null;
return {} return {};
}, },
methods: { methods: {
hasOneShowingChild(children = [], parent) { hasOneShowingChild(children = [], parent) {
if (!children) { if (!children) {
children = []; children = [];
} }
const showingChildren = children.filter(item => { const showingChildren = children.filter((item) => {
if (item.hidden) { if (item.hidden) {
return false return false;
} else { } else {
// Temp set(will be used if only has one showing child) // Temp set(will be used if only has one showing child)
this.onlyOneChild = item this.onlyOneChild = item;
return true return true;
} }
}) });
// When there is only one child router, the child router is displayed by default // When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) { if (showingChildren.length === 1) {
return true return true;
} }
// Show parent if there are no child router to display // Show parent if there are no child router to display
if (showingChildren.length === 0) { if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true } this.onlyOneChild = { ...parent, path: '', noShowingChildren: true };
return true return true;
} }
return false return false;
}, },
resolvePath(routePath) { resolvePath(routePath) {
if (isExternal(routePath)) { if (isExternal(routePath)) {
return routePath return routePath;
} }
if (isExternal(this.basePath)) { if (isExternal(this.basePath)) {
return this.basePath return this.basePath;
} }
return path.resolve(this.basePath, routePath) return path.resolve(this.basePath, routePath);
} },
} },
} };
</script> </script>

View File

@ -0,0 +1,106 @@
<template>
<div v-if="!item.hidden">
<template
v-if="
hasOneShowingChild(item.children, item) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.alwaysShow
">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item
:index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }">
<item icon="" :title="onlyOneChild.meta.title" />
</el-menu-item>
</app-link>
</template>
<el-submenu
v-else
ref="subMenu"
:index="resolvePath(item.path)"
popper-append-to-body>
<template slot="title">
<item v-if="item.meta" icon="" :title="item.meta.title" />
</template>
<sidebar-item-sub
v-for="(child, index) in item.children"
:key="child.path + index"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu" />
</el-submenu>
</div>
</template>
<script>
import path from 'path';
import { isExternal } from '@/utils/validate';
import Item from './Item';
import AppLink from './Link';
import FixiOSBug from './FixiOSBug';
export default {
name: 'SidebarItemSub',
components: { Item, AppLink },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true,
},
isNest: {
type: Boolean,
default: false,
},
basePath: {
type: String,
default: '',
},
},
data() {
this.onlyOneChild = null;
return {};
},
methods: {
hasOneShowingChild(children = [], parent) {
if (!children) {
children = [];
}
const showingChildren = children.filter((item) => {
if (item.hidden) {
return false;
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item;
return true;
}
});
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true;
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ...parent, path: '', noShowingChildren: true };
return true;
}
return false;
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath;
}
if (isExternal(this.basePath)) {
return this.basePath;
}
return path.resolve(this.basePath, routePath);
},
},
};
</script>

View File

@ -1,71 +0,0 @@
<template>
<div
:class="{ 'has-logo': showLogo }"
:style="{
backgroundColor:
settings.sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground,
}">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="
settings.sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground
"
:text-color="
settings.sideTheme === 'theme-dark'
? variables.menuColor
: variables.menuLightColor
"
:unique-opened="true"
active-text-color="#fff"
:collapse-transition="false"
mode="vertical">
<!-- 根据 sidebarRouters 路由生成菜单 -->
<sidebar-item
v-for="(route, index) in sidebarRouters"
:key="route.path + index"
:item="route"
:base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters, mapState } from 'vuex';
import Logo from './Logo';
import SidebarItem from './SidebarItem';
import variables from '@/assets/styles/variables.scss';
export default {
components: { SidebarItem, Logo },
computed: {
...mapState(['settings']),
...mapGetters(['sidebarRouters', 'sidebar']),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
},
},
};
</script>

View File

@ -1,6 +1,7 @@
<template> <template>
<div <div
:class="{ 'has-logo': showLogo }" :class="{ 'has-logo': showLogo }"
class="left-menu-box"
:style="{ :style="{
backgroundColor: backgroundColor:
settings.sideTheme === 'theme-dark' settings.sideTheme === 'theme-dark'
@ -49,9 +50,7 @@ export default {
...mapState(['settings']), ...mapState(['settings']),
...mapGetters(['sidebarRouters', 'sidebar', 'choicepart']), ...mapGetters(['sidebarRouters', 'sidebar', 'choicepart']),
routeList() { routeList() {
// return [this.partList[this.choicepart]] return this.sidebarRouters;
// return [this.sidebarRouters[29]]
return [this.sidebarRouters[this.choicepart]]
}, },
activeMenu() { activeMenu() {
const route = this.$route; const route = this.$route;
@ -74,3 +73,10 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss">
.left-menu-box {
.el-menu-item.is-active {
background-color: #0b58ff !important;
}
}
</style>

View File

@ -1,11 +1,11 @@
export default { export default {
data() { data() {
return { return {
tableH: this.tableHeight(260), tableH: this.tableHeight(296),
}; };
}, },
created() { created() {
this.tableH = this?.heightNum ? this.tableHeight(this.heightNum) : this.tableHeight(260); this.tableH = this?.heightNum ? this.tableHeight(this.heightNum) : this.tableHeight(296);
window.addEventListener('resize', this._setTableHeight); window.addEventListener('resize', this._setTableHeight);
}, },
destroyed() { destroyed() {
@ -13,7 +13,7 @@ export default {
}, },
methods: { methods: {
_setTableHeight() { _setTableHeight() {
this.tableH = this?.heightNum ? this.tableHeight(this.heightNum) : this.tableHeight(260); this.tableH = this?.heightNum ? this.tableHeight(this.heightNum) : this.tableHeight(296);
// this.tableH = this.tableHeight(260); // this.tableH = this.tableHeight(260);
}, },
}, },

View File

@ -71,7 +71,8 @@ export const constantRoutes = [
}, },
{ {
path: '/', path: '/',
component: () => import('@/views/choicePart'), // component: () => import('@/views/choicePart'),
component: () => import('@/views/home'),
hidden: true, hidden: true,
meta: { requireToken: true } meta: { requireToken: true }
}, },

View File

@ -13,7 +13,7 @@ module.exports = {
/** /**
* 是否显示顶部导航 * 是否显示顶部导航
*/ */
topNav: false, topNav: true,
/** /**
* 是否显示 tagsView * 是否显示 tagsView

View File

@ -23,10 +23,15 @@ const permission = {
state.topbarRouters = routes state.topbarRouters = routes
}, },
SET_SIDEBAR_ROUTERS: (state, routes) => { SET_SIDEBAR_ROUTERS: (state, routes) => {
console.log('==SET_SIDEBAR_ROUTERS==:',routes)
state.sidebarRouters = routes state.sidebarRouters = routes
}, },
}, },
actions: { actions: {
// 生成路由 // 生成路由
GenerateRoutes({commit}) { GenerateRoutes({commit}) {
return new Promise(resolve => { return new Promise(resolve => {

View File

@ -224,6 +224,10 @@ input, textarea{
left:20px; left:20px;
font-size:21px !important font-size:21px !important
} }
.el-message-box__input {
padding-left: 57px;
padding-right: 15px;
}
} }
.el-message-box__btns { .el-message-box__btns {
padding-right: 32px; padding-right: 32px;

View File

@ -0,0 +1,168 @@
<template>
<div class="navbar">
<div class="logo-container">
<img
src="../../../assets/images/cnbm.png"
style="
width: 34px;
height: 34px;
position: relative;
top: 9px;
margin-right: 8px;
"
alt="" />
MES产品化重构
</div>
<top-nav id="warnmenu-container" class="warnmenu-container" v-if="topNav" />
<div style="padding-top: 5px; padding-right: 38px">
<navbar-right :blackTitle="true" />
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import TopNav from './TopNav';
import Hamburger from '@/components/Hamburger';
import Screenfull from '@/components/Screenfull';
import SizeSelect from '@/components/SizeSelect';
import Search from '@/components/HeaderSearch';
import NotifyMessage from '@/layout/components/Message';
// import {getPath} from "@/utils/ruoyi";
import NavbarRight from './NavbarRight.vue';
export default {
components: {
TopNav,
Hamburger,
Screenfull,
SizeSelect,
Search,
NotifyMessage,
NavbarRight,
},
computed: {
...mapGetters(['sidebar', 'avatar', 'nickname', 'device']),
setting: {
get() {
return this.$store.state.settings.showSettings;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'showSettings',
value: val,
});
},
},
topNav: {
get() {
return this.$store.state.settings.topNav;
},
},
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar');
},
async logout() {
this.$modal
.confirm('确定注销并退出系统吗?', '提示')
.then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/');
});
})
.catch(() => {});
},
},
};
</script>
<style lang="scss" scoped>
.navbar {
height: 84px; // 56/48
overflow: hidden;
position: relative;
background-color: #fff;
.logo-container {
line-height: 84px;
height: 100%;
float: left;
cursor: pointer;
font-size: 26px;
padding-left: 40px;
font-weight: 500;
color: #0c0030;
}
.warnmenu-container {
position: absolute;
left: 290px;
}
.errLog-container {
display: inline-block;
vertical-align: top;
}
.right-menu {
float: right;
height: 100%;
line-height: 56px;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
&:hover {
background: rgba(0, 0, 0, 0.025);
}
}
}
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
display: flex;
justify-content: center;
align-items: center;
position: relative;
.user-avatar {
cursor: pointer;
width: 35px;
height: 35px;
border-radius: 50%;
}
.user-nickname {
margin-left: 5px;
font-size: 14px;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
}
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<div class="right-msg" :style="blackTitle ? 'color: #000' : 'color: #fff'">
<!-- <div class="home-icon" v-if="blackTitle">
<svg-icon
icon-class="alarm"
style="font-size: 24px; cursor: pointer"
@click="toHome" />
</div> -->
<!-- <div class="time-msg">
<div class="line1">{{timeZone}}&nbsp;&nbsp;&nbsp;&nbsp;{{topTime}}</div>
<div class="line2">{{topDate}}</div>
</div> -->
<div class="base-msg">
<div class="avatar">
<el-dropdown>
<img
:src="require(`../../../assets/images/choicepart/avatar.png`)"
alt=""
width="42"
height="42"
style="position: relative; top: 4px" />
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item>
<svg-icon icon-class="helpbtn" />
帮助文档
</el-dropdown-item> -->
<el-dropdown-item @click.native="logout">
<svg-icon icon-class="exitbtn" />
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="use-msg">
<div class="line1">{{ nickname }}</div>
<div class="line2">{{ dept }}</div>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
import { getUser } from '@/api/system/user.js';
import { getPath } from '@/utils/ruoyi';
export default {
name: 'navRight',
data() {
return {
// topDate: '',
// topTime: '',
// timeZone: '',
timer: '',
dept: ' ',
nickname: this.$store.getters.nickname,
};
},
props: {
blackTitle: {
type: Boolean,
default: () => {
return false;
},
},
},
created() {
this.getUserMsg();
// this.getTime();
},
beforeDestroy() {
clearInterval(this.timer);
},
methods: {
// getTime() {
// let _this = this;
// this.timer = setInterval(function () {
// _this.topDate = moment().format('YYYY/MM/DD');
// let temp = moment().format('A-hh:mm').split('-');
// _this.timeZone = temp[0];
// _this.topTime = temp[1];
// }, 1000);
// },
getUserMsg() {
let id = this.$store.getters.userId;
getUser(id).then((res) => {
this.dept = res.data.dept ? res.data.dept.name : '';
});
},
async logout() {
this.$modal
.confirm('确定注销并退出系统吗?', '提示')
.then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/');
});
})
.catch(() => {});
},
toHome() {
this.$router.push({ path: '/' });
},
},
};
</script>
<style lang="scss" scoped>
.right-msg {
float: right;
height: 84px;
font-size: 14px;
.time-msg {
display: inline-block;
margin-right: 30px;
}
.home-icon {
display: inline-block;
margin-right: 20px;
vertical-align: top;
line-height: 84px;
}
.base-msg {
display: inline-block;
padding-top: 10px;
.avatar {
display: inline-block;
margin-right: 10px;
}
.use-msg {
display: inline-block;
}
}
.line1 {
height: 19px;
}
.line2 {
height: 19px;
opacity: 0.65;
}
}
</style>

View File

@ -0,0 +1,273 @@
<template>
<el-menu
:default-active="activeMenu"
mode="horizontal"
@select="handleSelect">
<template v-for="(item, index) in topMenus">
<el-menu-item
:style="{ '--theme': theme }"
:index="item.path"
:key="index"
v-if="index < visibleNumber">
<!-- <svg-icon :icon-class="item.meta.icon" /> -->
<span class="menu-box">
<span class="menu-dot"></span>
{{ item.meta.title }}
</span>
</el-menu-item>
</template>
<!-- 顶部菜单超出数量折叠 -->
<el-submenu
:style="{ '--theme': theme }"
index="more"
v-if="topMenus.length > visibleNumber">
<template slot="title">更多菜单</template>
<template v-for="(item, index) in topMenus">
<el-menu-item
:index="item.path"
:key="index"
v-if="index >= visibleNumber">
<!-- <svg-icon :icon-class="item.meta.icon" /> -->
<span class="menu-box">
<span class="menu-dot"></span>
{{ item.meta.title }}
</span>
</el-menu-item>
</template>
</el-submenu>
</el-menu>
</template>
<script>
import { mapGetters } from 'vuex';
import { constantRoutes } from '@/router';
//
const hideList = ['/index', '/user/profile'];
export default {
data() {
return {
//
visibleNumber: 5,
// index
// currentIndex: undefined,
};
},
computed: {
...mapGetters(['choicepart']),
currentIndex() {
return this.choicepart;
},
theme() {
return this.$store.state.settings.theme;
},
//
topMenus() {
let topMenus = [];
this.routers.map((menu) => {
if (menu.hidden !== true) {
//
if (menu.path === '/') {
topMenus.push(menu.children[0]);
} else {
topMenus.push(menu);
}
}
});
console.log('topMenus:', topMenus);
return topMenus;
},
//
routers() {
return this.$store.state.permission.topbarRouters;
},
//
childrenMenus() {
const childrenMenus = [];
this.routers.map((router) => {
for (let item in router.children) {
if (router.children[item].parentPath === undefined) {
if (router.path === '/') {
router.children[item].path = '/' + router.children[item].path;
} else {
if (!this.ishttp(router.children[item].path)) {
router.children[item].path =
router.path + '/' + router.children[item].path;
}
}
router.children[item].parentPath = router.path;
}
childrenMenus.push(router.children[item]);
}
});
return constantRoutes.concat(childrenMenus);
},
//
activeMenu() {
const path = this.$route.path;
let activePath = path;
if (
path !== undefined &&
path.lastIndexOf('/') > 0 &&
hideList.indexOf(path) === -1
) {
const tmpPath = path.substring(1, path.length);
activePath = '/' + tmpPath.substring(0, tmpPath.indexOf('/'));
if (!this.$route.meta.link) {
this.$store.dispatch('app/toggleSideBarHide', false);
}
} else if (!this.$route.children) {
activePath = path;
this.$store.dispatch('app/toggleSideBarHide', true);
}
this.activeRoutes(activePath);
return activePath;
},
},
beforeMount() {
window.addEventListener('resize', this.setVisibleNumber);
},
beforeDestroy() {
window.removeEventListener('resize', this.setVisibleNumber);
},
mounted() {
this.setVisibleNumber();
},
methods: {
//
setVisibleNumber() {
const width = window.innerWidth - 700;
console.log(width);
console.log('window.innerWidth:', window.innerWidth);
this.visibleNumber = parseInt(width / 110);
console.log('this.visibleNumber:', this.visibleNumber);
},
//
handleSelect(key, keyPath) {
// this.currentIndex = key;
const route = this.routers.find((item) => item.path === key);
console.log('route:', route);
this.$store.dispatch('app/setChoicepart', key);
this.toRouter(route);
// if (this.ishttp(key)) {
// // http(s)://
// window.open(key, '_blank');
// console.log('aaaaaaaaaaaaaa');
// } else if (!route || !route.children) {
// //
// this.$router.push({ path: key });
// this.$store.dispatch('app/toggleSideBarHide', true);
// console.log('bbbbbbbbbbbbbbb');
// } else {
// //
// this.activeRoutes(key);
// if (!this.$route.meta.link) {
// this.$store.dispatch('app/toggleSideBarHide', false);
// }
// console.log('cccccccccccccccc');
// }
},
toRouter(item) {
console.log(item);
if (item.children) {
this.toRouter(item.children[0]);
} else {
this.$router.push({ name: item.name });
}
},
//
activeRoutes(key) {
const routes = [];
if (this.childrenMenus && this.childrenMenus.length > 0) {
this.childrenMenus.map((item) => {
if (
key === item.parentPath ||
(key === 'index' && '' === item.path)
) {
routes.push(item);
}
});
}
if (routes.length > 0) {
this.$store.commit('SET_SIDEBAR_ROUTERS', routes);
} else {
this.$store.dispatch('app/toggleSideBarHide', true);
}
},
ishttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
},
},
};
</script>
<style lang="scss">
.warnmenu-container.el-menu.el-menu--horizontal > .el-menu-item.is-active {
border-bottom: none !important;
}
.warnmenu-container.el-menu.el-menu--horizontal > .el-submenu.is-active {
--theme: none !important;
}
.warnmenu-container.el-menu--horizontal > .el-menu-item {
float: left;
height: 84px !important;
line-height: 84px !important;
color: #000 !important;
padding: 0 5px !important;
font-size: 18px;
.menu-box {
// color: #fff;
}
}
.warnmenu-container.el-menu--horizontal
> .el-menu-item:not(.is-disabled):hover {
background-color: transparent;
}
.warnmenu-container.el-menu {
background-color: transparent;
}
.warnmenu-container.el-menu.el-menu--horizontal {
border: none;
}
.warnmenu-container.el-menu--horizontal > .el-menu-item.is-active,
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133;
}
/* submenu item */
.warnmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
float: left;
height: 84px !important;
line-height: 91px !important;
color: #000 !important;
padding: 0 5px !important;
margin: 0 10px !important;
font-size: 18px;
}
.warnmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title:hover {
background-color: transparent;
}
.warnmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title i {
// color: #fff;
}
</style>
<style lang="scss" scoped>
.menu-box {
padding: 3px 10px 5px 10px;
border-radius: 30px;
color: #000;
}
.menu-dot {
display: inline-block;
width: 5px;
height: 5px;
border-radius: 50%;
background: #0b58ff;
margin-right: 3px;
margin-bottom: 2px;
opacity: 0;
}
</style>

View File

@ -0,0 +1,196 @@
<template>
<div class="warning-page">
<navbar />
<div class="main-box">
<div class="title">
<span></span>
异常警告
<div class="return-home" @click="toHome">
<svg-icon
icon-class="alarm-home"
style="font-size: 20px; position: relative; top: 2px" />
返回首页
</div>
</div>
<search-bar
:formConfigs="formConfig"
removeBlue
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
:page="1"
:limit="100000"
:table-props="tableProps"
:table-data="list"
:max-height="tableH" />
</div>
<div class="footer">
<img src="../../assets/img/alarm-bg.png" alt="" />
<div>&copy; 中建材智能自动化研究院有限公司</div>
</div>
</div>
</template>
<script>
import Navbar from './components/Navbar';
import moment from 'moment';
import tableHeightMixin from '@/mixins/tableHeightMixin';
export default {
name: 'AbnormalWarning',
mixins: [tableHeightMixin],
components: { Navbar },
data() {
return {
formConfig: [
{
type: 'input',
label: '报警来源',
placeholder: '报警来源',
param: 'content',
},
{
type: 'select',
label: '时间段',
selectOptions: [],
labelField: 'name',
valueField: 'id',
param: 'typeId',
filterable: true,
},
{
type: 'select',
label: '报警级别',
selectOptions: [],
labelField: 'name',
valueField: 'id',
param: 'typeId',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
],
heightNum: 280,
tableProps: [
{
prop: 'createTime',
label: '报警时间',
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{
prop: 'productionLineName1',
label: '报警来源',
showOverflowtooltip: true,
},
{
prop: 'productionLineName2',
label: '报警类型',
showOverflowtooltip: true,
},
{
prop: 'productionLineName3',
label: '报警级别',
showOverflowtooltip: true,
},
{
prop: 'productionLineName4',
label: '报警原因',
showOverflowtooltip: true,
},
{
prop: 'sectionName5',
label: '报警详情',
showOverflowtooltip: true,
},
],
list: [
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
],
};
},
created() {},
methods: {
buttonClick(val) {},
toHome() {
this.$router.push({ path: '/' });
},
},
};
</script>
<style lang="scss" scoped>
.warning-page {
width: 100%;
height: 100vh;
.main-box {
position: relative;
width: 64.58%;
height: calc(100vh - 160px);
background-color: #fff;
border-radius: 24px;
margin: 16px auto 0;
z-index: 10;
padding: 24px 32px;
.title {
font-size: 16px;
color: #000000;
position: relative;
cursor: pointer;
span {
display: inline-block;
float: left;
width: 4px;
height: 16px;
background-color: #0b58ff;
border-radius: 1px;
margin-right: 8px;
margin-top: 4px;
}
.return-home {
position: absolute;
color: rgba(0, 0, 0, 0.3);
font-size: 14px;
right: 0px;
top: 0px;
}
}
}
.footer {
position: fixed;
width: 100%;
bottom: -3px;
z-index: 8;
img {
width: 100%;
height: 220px;
}
div {
width: 100%;
color: red;
position: absolute;
bottom: 10px;
text-align: center;
font-size: 12px;
color: #c7c7c7;
letter-spacing: 1px;
}
}
}
</style>

View File

@ -1,8 +1,8 @@
/* /*
* @Author: zwq * @Author: zwq
* @Date: 2022-08-24 11:19:43 * @Date: 2022-08-24 11:19:43
* @LastEditors: DY * @LastEditors: zwq
* @LastEditTime: 2023-09-21 16:02:07 * @LastEditTime: 2024-07-22 11:15:10
* @Description: * @Description:
*/ */
export default { export default {
@ -17,7 +17,7 @@ export default {
}, },
tableData: [], tableData: [],
listQuery: { listQuery: {
pageSize: 10, pageSize: 20,
pageNo: 1, pageNo: 1,
total: 1, total: 1,
}, },
@ -101,11 +101,8 @@ export default {
}, },
// 删除 // 删除
deleteHandle(id, name, index) { deleteHandle(id, name, index) {
this.$confirm(`确定对${name ? '[名称=' + name + ']' : '[序号=' + index + ']'}进行删除操作?`, "提示", { this.$modal
confirmButtonText: "确定", .delConfirm(name ? '名称: ' + name : '序号: ' + index)
cancelButtonText: "取消",
type: "warning",
})
.then(() => { .then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => { this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({ this.$message({

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2024-07-01 14:53:55 * @Date: 2024-07-01 14:53:55
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2024-07-12 16:19:13 * @LastEditTime: 2024-07-22 15:20:51
* @Description: * @Description:
--> -->
<template> <template>
@ -54,6 +54,8 @@ import {
} from '@/api/base/groupClasses'; } from '@/api/base/groupClasses';
import GroupClassAdd from './components/groupClassAdd.vue'; import GroupClassAdd from './components/groupClassAdd.vue';
import StatusBtn from './components/statusBtn'; import StatusBtn from './components/statusBtn';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [ const tableProps = [
{ {
prop: 'name', prop: 'name',
@ -82,6 +84,7 @@ const tableProps = [
export default { export default {
name: 'GroupClass', name: 'GroupClass',
components: { GroupClassAdd }, components: { GroupClassAdd },
mixins: [tableHeightMixin],
data() { data() {
return { return {
formConfig: [ formConfig: [
@ -125,7 +128,6 @@ export default {
} }
: undefined, : undefined,
].filter((v) => v), ].filter((v) => v),
tableH: this.tableHeight(260),
// //
total: 0, total: 0,
// //
@ -143,9 +145,6 @@ export default {
}; };
}, },
created() { created() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260);
});
this.getList(); this.getList();
}, },
methods: { methods: {
@ -223,19 +222,18 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
console.log(row);
let _this = this; let _this = this;
if (row.enabled) { if (row.enabled) {
// //
_this.$modal _this.$modal
.confirm( .newConfirm(
'删除的班次"' + '删除的班次"' +
row.name + row.name +
'"可能会影响交接班计划,请点取消再次确认!' '"可能会影响交接班计划,请点取消再次确认!'
) ,'提示')
.then(function () { .then(function () {
return _this.$modal return _this.$modal
.confirm('是否确认删除班次名称为"' + row.name + '"的数据项?') .delConfirm('名称: ' + row.name)
.then(function () { .then(function () {
return deleteGroupClasses(row.id); return deleteGroupClasses(row.id);
}) })
@ -247,7 +245,7 @@ export default {
}); });
} else { } else {
_this.$modal _this.$modal
.confirm('是否确认删除班次名称为"' + row.name + '"的数据项?') .delConfirm('名称: ' + row.name)
.then(function () { .then(function () {
return deleteGroupClasses(row.id); return deleteGroupClasses(row.id);
}) })

View File

@ -1,12 +1,10 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<search-bar <search-bar
:formConfigs="formConfig" :formConfigs="formConfig"
ref="searchBarForm" ref="searchBarForm"
@headBtnClick="buttonClick" @headBtnClick="buttonClick" />
/>
<!-- 列表 --> <!-- 列表 -->
<base-table <base-table
:page="queryParams.pageNo" :page="queryParams.pageNo"
@ -14,23 +12,20 @@
:table-props="tableProps" :table-props="tableProps"
:table-data="list" :table-data="list"
:max-height="tableH" :max-height="tableH"
@emitFun="handleTableEvents" @emitFun="handleTableEvents">
>
<method-btn <method-btn
v-if="tableBtn.length" v-if="tableBtn.length"
slot="handleBtn" slot="handleBtn"
:width="80" :width="80"
label="操作" label="操作"
:method-list="tableBtn" :method-list="tableBtn"
@clickBtn="handleClick" @clickBtn="handleClick" />
/>
</base-table> </base-table>
<pagination <pagination
:page.sync="queryParams.pageNo" :page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.pageSize"
:total="total" :total="total"
@pagination="getList" @pagination="getList" />
/>
<!-- 新增 --> <!-- 新增 -->
<base-dialog <base-dialog
:dialogTitle="addOrEditTitle" :dialogTitle="addOrEditTitle"
@ -38,51 +33,57 @@
@cancel="handleCancel" @cancel="handleCancel"
@confirm="handleConfirm" @confirm="handleConfirm"
:before-close="handleCancel" :before-close="handleCancel"
width='40%' width="40%">
>
<group-team-add ref="groupList" @successSubmit="successSubmit" /> <group-team-add ref="groupList" @successSubmit="successSubmit" />
</base-dialog> </base-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getGroupTeamPage, deleteGroupTeam, updateGroupTeam } from "@/api/base/groupTeam"; import {
import { parseTime } from '@/utils/ruoyi' getGroupTeamPage,
import GroupTeamAdd from './components/groupTeamAdd' deleteGroupTeam,
import StatusBtn from './components/statusBtn' updateGroupTeam,
} from '@/api/base/groupTeam';
import { parseTime } from '@/utils/ruoyi';
import GroupTeamAdd from './components/groupTeamAdd';
import StatusBtn from './components/statusBtn';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [ const tableProps = [
{ {
prop: 'createTime', prop: 'createTime',
label: '创建时间', label: '创建时间',
filter: parseTime, filter: parseTime,
minWidth: 160 minWidth: 160,
}, },
{ {
prop: 'name', prop: 'name',
label: '班组名称' label: '班组名称',
}, },
{ {
prop: 'code', prop: 'code',
label: '编码', label: '编码',
minWidth: 220 minWidth: 220,
}, },
{ {
prop: 'num', prop: 'num',
label: '班组人数' label: '班组人数',
}, },
{ {
prop: 'leaderName', prop: 'leaderName',
label: '组长' label: '组长',
}, },
{ {
prop: 'enabled', prop: 'enabled',
label: '班组状态', label: '班组状态',
subcomponent: StatusBtn subcomponent: StatusBtn,
}, },
] ];
export default { export default {
name: "GroupTeam", name: 'GroupTeam',
components: { GroupTeamAdd }, components: { GroupTeamAdd },
mixins: [tableHeightMixin],
data() { data() {
return { return {
formConfig: [ formConfig: [
@ -90,53 +91,52 @@ export default {
type: 'input', type: 'input',
label: '班组名称', label: '班组名称',
placeholder: '班组名称', placeholder: '班组名称',
param: 'name' param: 'name',
}, },
{ {
type: 'input', type: 'input',
label: '组长', label: '组长',
placeholder: '组长', placeholder: '组长',
param: 'leaderName' param: 'leaderName',
}, },
{ {
type: 'button', type: 'button',
btnName: '查询', btnName: '查询',
name: 'search', name: 'search',
color: 'primary' color: 'primary',
}, },
{ {
type: 'separate' type: 'separate',
}, },
{ {
type: this.$auth.hasPermi('base:group-team:create') ? 'button' : '', type: this.$auth.hasPermi('base:group-team:create') ? 'button' : '',
btnName: '新增', btnName: '新增',
name: 'add', name: 'add',
color: 'success', color: 'success',
plain: true plain: true,
} },
], ],
tableProps, tableProps,
tableBtn: [ tableBtn: [
this.$auth.hasPermi('base:group-team:update') this.$auth.hasPermi('base:group-team:update')
? { ? {
type: 'edit', type: 'edit',
btnName: '编辑' btnName: '编辑',
} }
: undefined, : undefined,
this.$auth.hasPermi('base:group-team:delete') this.$auth.hasPermi('base:group-team:delete')
? { ? {
type: 'delete', type: 'delete',
btnName: '删除' btnName: '删除',
} }
: undefined : undefined,
].filter((v) => v), ].filter((v) => v),
tableH: this.tableHeight(260),
// //
total: 0, total: 0,
// //
list: [], list: [],
// //
addOrEditTitle: "", addOrEditTitle: '',
// //
centervisible: false, centervisible: false,
// //
@ -144,14 +144,11 @@ export default {
pageNo: 1, pageNo: 1,
pageSize: 20, pageSize: 20,
name: null, name: null,
code: null code: null,
}, },
}; };
}, },
created() { created() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260)
})
this.getList(); this.getList();
}, },
methods: { methods: {
@ -159,21 +156,21 @@ export default {
switch (val.btnName) { switch (val.btnName) {
case 'search': case 'search':
this.queryParams.pageNo = 1; this.queryParams.pageNo = 1;
this.queryParams.leaderName = val.leaderName this.queryParams.leaderName = val.leaderName;
this.queryParams.name = val.name this.queryParams.name = val.name;
this.getList() this.getList();
break break;
default: default:
this.addOrEditTitle = '新增' this.addOrEditTitle = '新增';
this.centervisible = true this.centervisible = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.groupList.init() this.$refs.groupList.init();
}) });
} }
}, },
/** 查询列表 */ /** 查询列表 */
getList() { getList() {
getGroupTeamPage(this.queryParams).then(response => { getGroupTeamPage(this.queryParams).then((response) => {
this.list = response.data.list; this.list = response.data.list;
this.total = response.data.total; this.total = response.data.total;
}); });
@ -181,54 +178,61 @@ export default {
handleClick(val) { handleClick(val) {
switch (val.type) { switch (val.type) {
case 'edit': case 'edit':
this.addOrEditTitle = '编辑' this.addOrEditTitle = '编辑';
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.groupList.init(val.data.id) this.$refs.groupList.init(val.data.id);
}) });
this.centervisible = true this.centervisible = true;
break break;
default: default:
this.handleDelete(val.data) this.handleDelete(val.data);
} }
}, },
// //
handleTableEvents(params) { handleTableEvents(params) {
if (params.name === 'state') {// if (params.name === 'state') {
updateGroupTeam({ ...params.payload }).then((res) => { //
updateGroupTeam({ ...params.payload })
.then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$modal.msgSuccess("操作成功"); this.$modal.msgSuccess('操作成功');
this.getList() this.getList();
} }
}).catch((res)=>{
this.getList()
}) })
.catch((res) => {
this.getList();
});
} }
}, },
handleCancel() { handleCancel() {
this.$refs.groupList.formClear() this.$refs.groupList.formClear();
this.centervisible = false this.centervisible = false;
this.addOrEditTitle = '' this.addOrEditTitle = '';
}, },
handleConfirm() { handleConfirm() {
this.$refs.groupList.submitForm() this.$refs.groupList.submitForm();
}, },
successSubmit() { successSubmit() {
this.handleCancel() this.handleCancel();
this.getList() this.getList();
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
this.$modal.confirm('是否确认删除班组名称为"' + row.name + '"的数据项?').then(function() { this.$modal
.delConfirm('名称: ' + row.name)
.then(function () {
return deleteGroupTeam(row.id); return deleteGroupTeam(row.id);
}).then(() => { })
.then(() => {
this.queryParams.pageNo = 1; this.queryParams.pageNo = 1;
this.getList(); this.getList();
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess('删除成功');
}).catch(() => {}); })
.catch(() => {});
}, },
closeDrawer() { closeDrawer() {
this.getList() this.getList();
} },
} },
}; };
</script> </script>

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2024-07-10 11:08:48 * @Date: 2024-07-10 11:08:48
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2024-07-12 16:19:28 * @LastEditTime: 2024-07-19 14:09:18
* @Description: * @Description:
--> -->
<template> <template>
@ -52,6 +52,7 @@ import {
} from '@/api/base/groupSchedulingPlan'; } from '@/api/base/groupSchedulingPlan';
import { listDept } from '@/api/system/dept'; import { listDept } from '@/api/system/dept';
import schedulingPlanConfigAdd from './components/schedulingPlanConfigAdd.vue'; import schedulingPlanConfigAdd from './components/schedulingPlanConfigAdd.vue';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [ const tableProps = [
{ {
prop: 'deptName', prop: 'deptName',
@ -78,6 +79,7 @@ const tableProps = [
export default { export default {
name: 'schedulingPlanConfig', name: 'schedulingPlanConfig',
components: { schedulingPlanConfigAdd }, components: { schedulingPlanConfigAdd },
mixins: [tableHeightMixin],
data() { data() {
return { return {
formConfig: [ formConfig: [
@ -129,7 +131,6 @@ export default {
} }
: undefined, : undefined,
].filter((v) => v), ].filter((v) => v),
tableH: this.tableHeight(260),
// //
total: 0, total: 0,
// //
@ -147,9 +148,6 @@ export default {
}; };
}, },
created() { created() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260);
});
listDept().then((response) => { listDept().then((response) => {
this.formConfig[0].selectOptions = response.data; this.formConfig[0].selectOptions = response.data;
}); });

View File

@ -47,6 +47,7 @@ import {
} from '@/api/base/groupSchedulingRule'; } from '@/api/base/groupSchedulingRule';
import schedulingRuleConfigAdd from './components/schedulingRuleConfigAdd.vue'; import schedulingRuleConfigAdd from './components/schedulingRuleConfigAdd.vue';
import { formatDate } from '@/utils'; import { formatDate } from '@/utils';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [ const tableProps = [
{ {
prop: 'enableTimeStr', prop: 'enableTimeStr',
@ -71,6 +72,7 @@ const tableProps = [
export default { export default {
name: 'schedulingRuleConfig', name: 'schedulingRuleConfig',
components: { schedulingRuleConfigAdd }, components: { schedulingRuleConfigAdd },
mixins: [tableHeightMixin],
data() { data() {
return { return {
formConfig: [ formConfig: [
@ -140,7 +142,6 @@ export default {
} }
: undefined, : undefined,
].filter((v) => v), ].filter((v) => v),
tableH: this.tableHeight(260),
// //
total: 0, total: 0,
// //
@ -158,9 +159,6 @@ export default {
}; };
}, },
created() { created() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260);
});
this.getList(); this.getList();
}, },
methods: { methods: {

View File

@ -31,6 +31,7 @@
import { getByWorkOrder } from '@/api/monitoring/groupTeamView' import { getByWorkOrder } from '@/api/monitoring/groupTeamView'
import { workOrderList } from '@/api/base/workOrder' import { workOrderList } from '@/api/base/workOrder'
import GroupTeamViewDetail from './components/groupTeamViewDetail.vue' import GroupTeamViewDetail from './components/groupTeamViewDetail.vue'
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [ const tableProps = [
{ {
prop: 'name', prop: 'name',
@ -51,6 +52,7 @@ const tableProps = [
] ]
export default { export default {
name: 'GroupTeamView', name: 'GroupTeamView',
mixins: [tableHeightMixin],
data() { data() {
return { return {
formConfig: [ formConfig: [
@ -86,16 +88,12 @@ export default {
: undefined : undefined
].filter((v) => v), ].filter((v) => v),
tableProps, tableProps,
tableH: this.tableHeight(220),
list: [], list: [],
paramVisible: false paramVisible: false
} }
}, },
components: { GroupTeamViewDetail }, components: { GroupTeamViewDetail },
mounted() { mounted() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(220)
})
this.getOrderList() this.getOrderList()
}, },
methods: { methods: {

View File

@ -37,6 +37,7 @@
import { groupTeamSchedulingPage, groupClassesListAll } from '@/api/monitoring/teamProduction' import { groupTeamSchedulingPage, groupClassesListAll } from '@/api/monitoring/teamProduction'
import { parseTime } from '@/utils/ruoyi' import { parseTime } from '@/utils/ruoyi'
import TeamProductionDetail from './components/teamProductionDetail' import TeamProductionDetail from './components/teamProductionDetail'
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [ const tableProps = [
{ {
prop: 'createTime', prop: 'createTime',
@ -74,6 +75,7 @@ const tableProps = [
] ]
export default { export default {
name: 'GroupTeamScheduling', name: 'GroupTeamScheduling',
mixins: [tableHeightMixin],
data() { data() {
return { return {
formConfig: [ formConfig: [
@ -126,16 +128,12 @@ export default {
: undefined : undefined
].filter((v) => v), ].filter((v) => v),
list: [], list: [],
tableH: this.tableHeight(260),
total: 0, total: 0,
paramVisible: false paramVisible: false
} }
}, },
components: { TeamProductionDetail }, components: { TeamProductionDetail },
mounted() { mounted() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260)
})
this.getGroupClass() this.getGroupClass()
this.getList() this.getList()
}, },

View File

@ -0,0 +1,167 @@
<template>
<div class="navbar">
<div class="logo-container">
<img
src="../../../assets/images/cnbm.png"
style="
width: 34px;
height: 34px;
position: relative;
top: 9px;
margin-right: 8px;
"
alt="" />
MES产品化重构
</div>
<top-nav id="homemenu-container" class="homemenu-container" v-if="topNav" />
<div style="padding-top: 5px; padding-right: 24px">
<navbar-right :blackTitle="true" />
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import TopNav from './TopNav';
import Hamburger from '@/components/Hamburger';
import Screenfull from '@/components/Screenfull';
import SizeSelect from '@/components/SizeSelect';
import Search from '@/components/HeaderSearch';
import NotifyMessage from '@/layout/components/Message';
// import {getPath} from "@/utils/ruoyi";
import NavbarRight from './NavbarRight.vue';
export default {
components: {
TopNav,
Hamburger,
Screenfull,
SizeSelect,
Search,
NotifyMessage,
NavbarRight,
},
computed: {
...mapGetters(['sidebar', 'avatar', 'nickname', 'device']),
setting: {
get() {
return this.$store.state.settings.showSettings;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'showSettings',
value: val,
});
},
},
topNav: {
get() {
return this.$store.state.settings.topNav;
},
},
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar');
},
async logout() {
this.$modal
.confirm('确定注销并退出系统吗?', '提示')
.then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/');
});
})
.catch(() => {});
},
},
};
</script>
<style lang="scss" scoped>
.navbar {
height: 84px; // 56/48
overflow: hidden;
position: relative;
.logo-container {
color: #fff;
line-height: 84px;
height: 100%;
float: left;
cursor: pointer;
font-size: 26px;
padding-left: 40px;
font-weight: 500;
}
.homemenu-container {
position: absolute;
left: 290px;
}
.errLog-container {
display: inline-block;
vertical-align: top;
}
.right-menu {
float: right;
height: 100%;
line-height: 56px;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
&:hover {
background: rgba(0, 0, 0, 0.025);
}
}
}
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
display: flex;
justify-content: center;
align-items: center;
position: relative;
.user-avatar {
cursor: pointer;
width: 35px;
height: 35px;
border-radius: 50%;
}
.user-nickname {
margin-left: 5px;
font-size: 14px;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
}
}
</style>

View File

@ -0,0 +1,143 @@
<template>
<div class="right-msg" :style="blackTitle ? 'color: #000' : 'color: #fff'">
<div class="home-icon" v-if="blackTitle">
<!-- <svg-icon
icon-class="home"
style="font-size: 24px; cursor: pointer"
@click="toHome" /> -->
<svg-icon
icon-class="home-alarm-white"
style="font-size: 24px; cursor: pointer"
@click="toAlarm" />
</div>
<!-- <div class="time-msg">
<div class="line1">{{timeZone}}&nbsp;&nbsp;&nbsp;&nbsp;{{topTime}}</div>
<div class="line2">{{topDate}}</div>
</div> -->
<div class="base-msg">
<div class="avatar">
<el-dropdown>
<img
:src="require(`../../../assets/images/choicepart/avatar.png`)"
alt=""
width="42"
height="42"
style="position: relative; top: 4px" />
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item>
<svg-icon icon-class="helpbtn" />
帮助文档
</el-dropdown-item> -->
<el-dropdown-item @click.native="logout">
<svg-icon icon-class="exitbtn" />
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="use-msg">
<div class="line1">{{ nickname }}</div>
<div class="line2">{{ dept }}</div>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
import { getUser } from '@/api/system/user.js';
import { getPath } from '@/utils/ruoyi';
export default {
name: 'navRight',
data() {
return {
// topDate: '',
// topTime: '',
// timeZone: '',
timer: '',
dept: ' ',
nickname: this.$store.getters.nickname,
};
},
props: {
blackTitle: {
type: Boolean,
default: () => {
return false;
},
},
},
created() {
this.getUserMsg();
// this.getTime();
},
// beforeDestroy() {
// clearInterval(this.timer);
// },
methods: {
// getTime() {
// let _this = this;
// this.timer = setInterval(function () {
// _this.topDate = moment().format('YYYY/MM/DD');
// let temp = moment().format('A-hh:mm').split('-');
// _this.timeZone = temp[0];
// _this.topTime = temp[1];
// }, 1000);
// },
getUserMsg() {
let id = this.$store.getters.userId;
getUser(id).then((res) => {
this.dept = res.data.dept ? res.data.dept.name : '';
});
},
async logout() {
this.$modal
.confirm('确定注销并退出系统吗?', '提示')
.then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/');
});
})
.catch(() => {});
},
toAlarm() {
this.$router.push({ path: '/abnormalWarning' });
},
},
};
</script>
<style lang="scss" scoped>
.right-msg {
float: right;
height: 84px;
font-size: 14px;
.time-msg {
display: inline-block;
margin-right: 30px;
}
.home-icon {
display: inline-block;
margin-right: 20px;
vertical-align: top;
line-height: 84px;
}
.base-msg {
display: inline-block;
padding-top: 10px;
.avatar {
display: inline-block;
margin-right: 10px;
}
.use-msg {
display: inline-block;
color: #fff;
}
}
.line1 {
height: 19px;
}
.line2 {
height: 19px;
opacity: 0.65;
}
}
</style>

View File

@ -0,0 +1,273 @@
<template>
<el-menu
:default-active="activeMenu"
mode="horizontal"
@select="handleSelect">
<template v-for="(item, index) in topMenus">
<el-menu-item
:style="{ '--theme': theme }"
:index="item.path"
:key="index"
v-if="index < visibleNumber">
<!-- <svg-icon :icon-class="item.meta.icon" /> -->
<span class="menu-box">
<span class="menu-dot"></span>
{{ item.meta.title }}
</span>
</el-menu-item>
</template>
<!-- 顶部菜单超出数量折叠 -->
<el-submenu
:style="{ '--theme': theme }"
index="more"
v-if="topMenus.length > visibleNumber">
<template slot="title">更多菜单</template>
<template v-for="(item, index) in topMenus">
<el-menu-item
:index="item.path"
:key="index"
v-if="index >= visibleNumber">
<!-- <svg-icon :icon-class="item.meta.icon" /> -->
<span class="menu-box">
<span class="menu-dot"></span>
{{ item.meta.title }}
</span>
</el-menu-item>
</template>
</el-submenu>
</el-menu>
</template>
<script>
import { mapGetters } from 'vuex';
import { constantRoutes } from '@/router';
//
const hideList = ['/index', '/user/profile'];
export default {
data() {
return {
//
visibleNumber: 5,
// index
// currentIndex: undefined,
};
},
computed: {
...mapGetters(['choicepart']),
currentIndex() {
return this.choicepart;
},
theme() {
return this.$store.state.settings.theme;
},
//
topMenus() {
let topMenus = [];
this.routers.map((menu) => {
if (menu.hidden !== true) {
//
if (menu.path === '/') {
topMenus.push(menu.children[0]);
} else {
topMenus.push(menu);
}
}
});
console.log('topMenus:', topMenus);
return topMenus;
},
//
routers() {
return this.$store.state.permission.topbarRouters;
},
//
childrenMenus() {
const childrenMenus = [];
this.routers.map((router) => {
for (let item in router.children) {
if (router.children[item].parentPath === undefined) {
if (router.path === '/') {
router.children[item].path = '/' + router.children[item].path;
} else {
if (!this.ishttp(router.children[item].path)) {
router.children[item].path =
router.path + '/' + router.children[item].path;
}
}
router.children[item].parentPath = router.path;
}
childrenMenus.push(router.children[item]);
}
});
return constantRoutes.concat(childrenMenus);
},
//
activeMenu() {
const path = this.$route.path;
let activePath = path;
if (
path !== undefined &&
path.lastIndexOf('/') > 0 &&
hideList.indexOf(path) === -1
) {
const tmpPath = path.substring(1, path.length);
activePath = '/' + tmpPath.substring(0, tmpPath.indexOf('/'));
if (!this.$route.meta.link) {
this.$store.dispatch('app/toggleSideBarHide', false);
}
} else if (!this.$route.children) {
activePath = path;
this.$store.dispatch('app/toggleSideBarHide', true);
}
this.activeRoutes(activePath);
return activePath;
},
},
beforeMount() {
window.addEventListener('resize', this.setVisibleNumber);
},
beforeDestroy() {
window.removeEventListener('resize', this.setVisibleNumber);
},
mounted() {
this.setVisibleNumber();
},
methods: {
//
setVisibleNumber() {
const width = window.innerWidth - 700;
console.log(width);
console.log('window.innerWidth:', window.innerWidth);
this.visibleNumber = parseInt(width / 110);
console.log('this.visibleNumber:', this.visibleNumber);
},
//
handleSelect(key, keyPath) {
// this.currentIndex = key;
const route = this.routers.find((item) => item.path === key);
console.log('route:', route);
this.$store.dispatch('app/setChoicepart', key);
this.toRouter(route);
// if (this.ishttp(key)) {
// // http(s)://
// window.open(key, '_blank');
// console.log('aaaaaaaaaaaaaa');
// } else if (!route || !route.children) {
// //
// this.$router.push({ path: key });
// this.$store.dispatch('app/toggleSideBarHide', true);
// console.log('bbbbbbbbbbbbbbb');
// } else {
// //
// this.activeRoutes(key);
// if (!this.$route.meta.link) {
// this.$store.dispatch('app/toggleSideBarHide', false);
// }
// console.log('cccccccccccccccc');
// }
},
toRouter(item) {
console.log(item);
if (item.children) {
this.toRouter(item.children[0]);
} else {
this.$router.push({ name: item.name });
}
},
//
activeRoutes(key) {
const routes = [];
if (this.childrenMenus && this.childrenMenus.length > 0) {
this.childrenMenus.map((item) => {
if (
key === item.parentPath ||
(key === 'index' && '' === item.path)
) {
routes.push(item);
}
});
}
if (routes.length > 0) {
this.$store.commit('SET_SIDEBAR_ROUTERS', routes);
} else {
this.$store.dispatch('app/toggleSideBarHide', true);
}
},
ishttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
},
},
};
</script>
<style lang="scss">
.homemenu-container.el-menu.el-menu--horizontal > .el-submenu.is-active {
--theme: none !important;
}
.homemenu-container.el-menu.el-menu--horizontal > .el-menu-item.is-active {
border-bottom: none !important;
}
.homemenu-container.el-menu--horizontal > .el-menu-item {
float: left;
height: 84px !important;
line-height: 84px !important;
color: #999093 !important;
padding: 0 5px !important;
font-size: 18px;
.menu-box {
color: #fff;
}
}
.homemenu-container.el-menu--horizontal
> .el-menu-item:not(.is-disabled):hover {
background-color: transparent;
}
.homemenu-container.el-menu {
background-color: transparent;
}
.homemenu-container.el-menu.el-menu--horizontal {
border: none;
}
.homemenu-container.el-menu--horizontal > .el-menu-item.is-active,
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133;
}
/* submenu item */
.homemenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
float: left;
height: 84px !important;
line-height: 91px !important;
color: #fff !important;
padding: 0 5px !important;
margin: 0 10px !important;
font-size: 18px;
}
.homemenu-container.el-menu--horizontal > .el-submenu .el-submenu__title:hover {
background-color: transparent;
}
.homemenu-container.el-menu--horizontal > .el-submenu .el-submenu__title i {
color: #fff;
}
</style>
<style lang="scss" scoped>
.menu-box {
padding: 3px 10px 5px 10px;
border-radius: 30px;
color: #000;
}
.menu-dot {
display: inline-block;
width: 5px;
height: 5px;
border-radius: 50%;
background: #0b58ff;
margin-right: 3px;
margin-bottom: 2px;
opacity: 0;
}
</style>

444
src/views/home/index.vue Normal file
View File

@ -0,0 +1,444 @@
<template>
<div class="home-page">
<div>
<navbar />
</div>
<div class="date-tabs">
<el-tabs v-model="activeName" :stretch="true">
<el-tab-pane
:label="'\u2002\u2002日\u2002\u2002'"
name="日"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002周\u2002\u2002'"
name="周"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002月\u2002\u2002'"
name="月"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002年\u2002\u2002'"
name="年"></el-tab-pane>
</el-tabs>
<div class="current-date">(6.13-6.20)</div>
<div class="current-time">
<span style="display: inline-block; margin-right: 16px">
{{ topTime + timeZone }}
</span>
<span>{{ topDate }}</span>
</div>
</div>
<el-row class="main-top" :gutter="16">
<el-col :span="12" style="position: relative">
<div class="title">
<svg-icon icon-class="home-produce" />
<span class="title-inner">生产总览</span>
</div>
<el-row class="box">
<el-col :span="6" class="num-box shadow">
<div class="num-style">9,301.01</div>
<div class="unit-style">产量/千片</div>
</el-col>
<el-col :span="4" class="num-box shadow">
<div class="num-style">94.34</div>
<div class="unit-style">良品率/%</div>
</el-col>
<el-col :span="8" class="num-box shadow">
<div class="num-style">29,301.01</div>
<div class="unit-style">完成工单数量/千片</div>
</el-col>
<el-col :span="6" class="num-box">
<div class="num-style">1,340</div>
<div class="unit-style">完成订单数量/</div>
</el-col>
</el-row>
</el-col>
<el-col :span="12" style="position: relative">
<div class="title">
<svg-icon icon-class="home-device" />
<span class="title-inner">设备总览</span>
</div>
<el-row class="box">
<el-col :span="6" class="num-box shadow">
<div class="num-style">2,931</div>
<div class="unit-style">设备总数/</div>
</el-col>
<el-col :span="6" class="num-box shadow">
<div class="num-style">931</div>
<div class="unit-style">在线设备总数/</div>
</el-col>
<el-col :span="6" class="num-box shadow">
<div class="num-style">7</div>
<div class="unit-style">故障设备总数/</div>
</el-col>
<el-col :span="6" class="num-box">
<div class="num-style">0</div>
<div class="unit-style">停机设备总数/</div>
</el-col>
</el-row>
</el-col>
</el-row>
<div class="main-middle">
<div
class="item"
:class="{ shadow: index !== middleMenu.length - 1 }"
v-for="(item, index) in middleMenu"
:key="index">
<div style="width: 160px; margin: 0 auto; padding-top: 20px">
<svg-icon :icon-class="item.icon" style="font-size: 56px" />
<div class="title-box">
<div class="title">{{ item.name }}</div>
<div class="triangle">
<span class="c1"></span>
<span class="c2"></span>
<span class="c3"></span>
</div>
</div>
</div>
</div>
</div>
<el-row class="main-bottom" :gutter="16">
<el-col :span="12">
<div class="box">
<div class="title-box">
<svg-icon icon-class="home-order-monitor" />
<span class="title">工单监控</span>
</div>
<div class="order-box">
<div
class="order-item"
v-for="(item, index) in orderList"
:key="index">
<div>
<span class="order-name">{{ item.name }}</span>
<span class="order-value">{{ item.value }}%</span>
</div>
<el-progress
:percentage="item.value"
:text-inside="false"
:stroke-width="15"
:show-text="false"></el-progress>
</div>
</div>
</div>
</el-col>
<el-col :span="12">
<div class="box">
<div class="title-box">
<svg-icon icon-class="home-device-alarm" />
<span class="title">设备告警</span>
</div>
<base-table
:page="1"
:limit="100000"
:table-props="tableProps"
:table-data="list"
:max-height="tableH" />
</div>
</el-col>
</el-row>
<div
class="main-footer"
style="
color: #c7c7c7;
user-select: none;
font-size: 14px;
letter-spacing: 1px;
height: 30px;
display: grid;
place-content: center;
">
&copy; 中建材智能自动化研究院有限公司
</div>
</div>
</template>
<script>
import Navbar from './components/Navbar';
import moment from 'moment';
import tableHeightMixin from '@/mixins/tableHeightMixin';
export default {
name: 'Home',
mixins: [tableHeightMixin],
components: { Navbar },
computed: {
gradientBackground() {
return {
'background-image':
'linear-gradient(90deg, #f0f0f0 25%, rgba(255, 255, 255, 0) 25%, rgba(255, 255, 255, 0) 50%, #f0f0f0 50%, #f0f0f0 75%, rgba(255, 255, 255, 0) 75%, rgba(255, 255, 255, 0))',
'background-size': '100px 100px', //
};
},
},
data() {
return {
activeName: '日',
topDate: '',
topTime: '',
timeZone: '',
middleMenu: [
{ name: '工单管理', url: '', icon: 'home-work-menu' },
{ name: '订单管理', url: '', icon: 'home-order-menu' },
{ name: '设备管理', url: '', icon: 'home-device-menu' },
{ name: '质量管理', url: '', icon: 'home-quality-menu' },
{ name: '仓库管理', url: '', icon: 'home-store-menu' },
],
orderList: [
{ name: '工单1', value: 50 },
{ name: '工单2', value: 60 },
{ name: '工单3', value: 30 },
{ name: '工单4', value: 60 },
{ name: '工单5', value: 10 },
{ name: '工单6', value: 60 },
{ name: '工单7', value: 40 },
{ name: '工单8', value: 70 },
{ name: '工单9', value: 90 },
],
heightNum: 640,
tableProps: [
{
prop: 'productionLineName',
label: '设备名称',
showOverflowtooltip: true,
},
{
prop: 'sectionName',
label: '告警内容',
showOverflowtooltip: true,
},
{
prop: 'createTime',
label: '告警时间',
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
],
list: [
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
],
};
},
created() {
this.getTime();
},
beforeDestroy() {
clearInterval(this.timer);
},
methods: {
getTime() {
let _this = this;
this.timer = setInterval(function () {
_this.topDate = moment().format('YYYY.MM.DD');
let temp = moment().format('A-hh:mm').split('-');
_this.timeZone = temp[0];
_this.topTime = temp[1];
}, 1000);
},
},
};
</script>
<style lang="scss" scoped>
.home-page {
background-image: url('~@/assets/img/home-bg.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
height: 300px;
width: 100%;
}
.date-tabs {
padding-left: 40px;
padding-top: 20px;
position: relative;
}
:deep(.date-tabs) {
.el-tabs__header {
margin-bottom: 8px;
display: inline-block;
transform: translateY(-12px);
}
.el-tabs__content {
overflow: visible;
}
.el-tabs__item {
font-size: 18px;
color: #fff;
padding-left: 0 !important;
padding-right: 0 !important;
line-height: 36px !important;
height: 36px;
}
.el-tabs__item.is-active {
color: #0b58ff;
}
}
.current-date {
color: #fff;
font-size: 18px;
position: absolute;
left: 260px;
top: 14px;
}
.current-time {
color: #fff;
font-size: 18px;
position: absolute;
right: 38px;
top: 14px;
}
.main-top {
width: 100%;
padding: 0 20px 0 40px;
.title {
position: absolute;
left: 34px;
top: 20px;
width: 180px;
font-size: 32px;
z-index: 10;
.title-inner {
position: absolute;
left: 42px;
top: 5px;
font-size: 24px;
}
}
.box {
background-color: #fff;
border-radius: 24px;
height: 192px;
padding: 40px 24px 32px 24px;
.num-box {
height: 120px;
padding-top: 26px;
text-align: center;
.num-style {
color: #000;
font-size: 40px;
}
.unit-style {
color: rgba(0, 0, 0, 0.7);
font-size: 18px;
}
}
.shadow {
background: linear-gradient(90deg, #ffffff 80%, #f2f4f9 100%);
}
}
}
.main-middle {
display: flex;
flex-flow: row nowrap;
background-color: #fff;
border-radius: 24px;
height: 133px;
margin: 16px 38px 16px 40px;
padding-top: 15px;
.item {
width: 20%;
height: 100px;
cursor: pointer;
.title-box {
display: inline-block;
padding-left: 20px;
vertical-align: bottom;
.title {
height: 35px;
font-size: 18px;
color: #000;
padding-top: 6px;
letter-spacing: 2px;
}
.triangle {
height: 15px;
span {
display: inline-block;
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
}
.c1 {
border-left: 12px solid rgba(11, 88, 255, 1);
margin-right: 5px;
}
.c2 {
border-left: 12px solid rgba(11, 88, 255, 0.5);
margin-right: 5px;
}
.c3 {
border-left: 12px solid rgba(11, 88, 255, 0.2);
}
}
}
}
.shadow {
background: linear-gradient(90deg, #ffffff 90%, #f2f4f9 100%);
}
}
.main-bottom {
width: 100%;
padding: 0 20px 0 40px;
.box {
background-color: #fff;
border-radius: 24px;
height: calc(100vh - 534px);
padding: 24px;
.title-box {
position: relative;
font-size: 32px;
margin-bottom: 16px;
.title {
position: absolute;
left: 44px;
top: 6px;
font-size: 24px;
}
}
.order-box {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
font-size: 18px;
padding: 0 30px;
.order-item {
width: 48%;
margin-bottom: 16px;
position: relative;
.order-name {
color: #000000;
}
.order-value {
position: absolute;
right: 0;
color: #0b58ff;
}
}
}
}
}
</style>
<style lang="scss">
.home-page {
.el-progress-bar__inner {
background-image: url('~@/assets/img/home-progress-bg.png');
background-size: cover;
}
}
</style>

View File

@ -0,0 +1,223 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-08-05 16:12:18
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="物料产品名称" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入物料产品名称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="物料产品编码" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入物料产品编码" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="物料产品类型" prop="typeId">
<treeselect
v-model="dataForm.typeId"
:options="deptOptions"
:normalizer="normalizer"
@select="setShowTime"
:show-count="true"
:appendToBody="true"
z-index="99999"
placeholder="选择物料产品类型" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="单位" prop="unit">
<el-select
v-model="dataForm.unit"
filterable
style="width: 100%"
placeholder="请选择单位">
<el-option
v-for="dict in getDictDatas(DICT_TYPE.UNIT_DICT)"
:key="dict.value"
:label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="规格" prop="specifications">
<el-input
v-model="dataForm.specifications"
clearable
placeholder="请输入规格" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="供应商" prop="supplierId">
<el-select
v-model="dataForm.supplierId"
filterable
clearable
:style="{ width: '100%' }"
placeholder="请选择供应商">
<el-option
v-for="item in supplierArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" v-if="showTime">
<el-form-item label="生产单位用时" prop="processTime">
<el-input
v-model.number="dataForm.processTime"
type="number"
clearable
placeholder="请输入产线生产单位用时" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
clearable
placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../mixins/basic-add';
import { getTreeArr } from '../mixins/code-filter';
import {
createProductMaterial,
updateProductMaterial,
getProductMaterial,
getProductMaterialCode,
getSupplierList,
getMaterialTree,
} from '@/api/base/material';
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
export default {
mixins: [basicAdd],
components: {
Treeselect,
},
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getProductMaterialCode,
createURL: createProductMaterial,
updateURL: updateProductMaterial,
infoURL: getProductMaterial,
},
deptOptions: undefined,
showTime: false,
dataForm: {
id: undefined,
code: undefined,
name: '',
typeId: undefined,
unit: undefined,
specifications: undefined,
supplierId: undefined,
processTime: 0,
remark: undefined,
},
supplierArr: [],
treeArr: [],
dataRule: {
code: [{ required: true, message: '编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
typeId: [
{
required: true,
message: '物料产品类型不能为空',
trigger: 'blur',
},
],
},
};
},
mounted() {},
methods: {
init(id) {
this.dataForm.id = id || '';
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
this.urlOptions.infoURL(id).then((response) => {
this.dataForm = response.data;
this.setDataForm();
});
} else {
if (this.urlOptions.isGetCode) {
this.getCode();
this.setDataForm();
}
}
});
},
typeId(typeId, product) {
this.$nextTick(() => {
this.dataForm.typeId = typeId || undefined;
this.showTime = product || false;
});
},
setDataForm() {
getSupplierList().then((res) => {
this.supplierArr = res.data;
});
//
getMaterialTree().then((response) => {
this.deptOptions = [];
this.deptOptions.push(...this.handleTree(response.data, 'id'));
this.$nextTick(() => {
if (this.dataForm.id) {
this.treeArr = [];
this.treeArr = getTreeArr(response.data);//
this.showTime = this.treeArr.find(
(item) => item.id == this.dataForm.typeId
).product;
}
});
});
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children,
};
},
setShowTime(node) {
this.showTime = node.product || false;
},
},
};
</script>

View File

@ -0,0 +1,141 @@
<template>
<el-dialog
:visible.sync="visible"
:width="'30%'"
:append-to-body="true"
:close-on-click-modal="false"
class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">
{{ !dataForm.id ? '新增' : '编辑' }}
</div>
</slot>
</template>
<el-form
ref="dataForm"
:model="dataForm"
:rules="dataRule"
label-width="70px"
@keyup.enter.native="dataFormSubmit()">
<el-form-item label="属性名" prop="attrName">
<el-input
v-model="dataForm.attrName"
placeholder="请输入属性名"
clearable />
</el-form-item>
<el-form-item label="属性值" prop="attrValue">
<el-input
v-model="dataForm.attrValue"
placeholder="请输入属性值"
clearable />
</el-form-item>
</el-form>
<el-row style="text-align: right">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</el-row>
</el-dialog>
</template>
<script>
import {
createMaterialAttr,
updateMaterialAttr,
getMaterialAttr
} from '@/api/base/material';
export default {
props: {
materialId: {
type: String,
default: '',
},
},
data() {
return {
visible: false,
dataForm: {
id: undefined,
attrName: '',
attrValue: '',
},
dataRule: {
attrName: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
},
};
},
methods: {
init(id) {
this.dataForm.id = id || '';
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
getMaterialAttr({
id: this.dataForm.id
}).then((res) => {
const { attrName, attrValue } = res.data;
this.dataForm.attrName = attrName;
this.dataForm.attrValue = attrValue;
});
}
});
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
//
if (this.dataForm.id) {
updateMaterialAttr({
...this.dataForm,
materialId: this.materialId,
}).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
createMaterialAttr({
...this.dataForm,
materialId: this.materialId,
}).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
});
}
});
},
},
};
</script>
<style scoped>
.dialog >>> .el-dialog__body {
padding: 30px 24px;
}
.dialog >>> .el-dialog__header {
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
padding: 13px 24px;
border-bottom: 1px solid #e9e9e9;
}
.dialog >>> .el-dialog__header .titleStyle::before {
content: '';
display: inline-block;
width: 4px;
height: 16px;
background-color: #0b58ff;
border-radius: 1px;
margin-right: 8px;
position: relative;
top: 2px;
}
</style>

View File

@ -0,0 +1,466 @@
<!--
* @Author: zwq
* @Date: 2024-07-01 14:54:06
* @LastEditors: zwq
* @LastEditTime: 2024-08-08 16:46:44
* @Description:
-->
<template>
<div style="display: flex; gap: 16px; flex: 1; background: #eff1f6">
<div
class="app-container"
style="background: white; width: 280px; border-radius: 8px">
<div class="head-container">
<el-input
v-model="treeName"
placeholder="请输入名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px" />
</div>
<div class="head-container">
<el-tree
v-loading="treeLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
:data="deptOptions1"
:props="defaultProps"
node-key="id"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
default-expand-all
highlight-current
@node-click="handleNodeClick">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span style="float: right" v-if="data.parentId !== -1">
<el-button
class="btnHover"
type="text"
icon="el-icon-edit"
size="mini"
v-if="data.parentId !== 0"
@click="() => edit(node, data)" />
<el-button
class="btnHover"
type="text"
icon="el-icon-circle-plus-outline"
size="mini"
@click="() => append(data)" />
<el-button
class="btnHover"
type="text"
icon="el-icon-remove-outline"
size="mini"
v-if="data.parentId !== 0"
@click="() => remove(node, data)" />
</span>
</span>
</el-tree>
</div>
</div>
<div
class="app-container"
style="background: #fff; border-radius: 8px; width: 1px; flex: 1">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:max-height="tableH"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
<!-- 添加或修改菜单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="700px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="父类型">
<treeselect
v-model="form.parentId"
:options="deptOptions"
:normalizer="normalizer"
:show-count="true"
:appendToBody="true"
z-index="99999"
placeholder="选择父类型" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="请输入名称" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../mixins/basic-page';
import { parseTime } from '../mixins/code-filter';
import { publicFormatter } from '@/utils/dict';
import {
getProductMaterialPage,
deleteProductMaterial,
getMaterialTree,
createMaterialTree,
updateMaterialTree,
deleteMaterialTree,
} from '@/api/base/material';
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime,
width: 150,
},
{
prop: 'name',
label: '物料产品名称',
},
{
prop: 'code',
label: '物料产品编码',
width: 160,
},
{
prop: 'typeNameChain',
label: '物料产品类型',
},
{
prop: 'unit',
label: '单位',
filter: publicFormatter('unit_dict'),
width: 60,
},
{
prop: 'specifications',
label: '规格',
},
{
prop: 'supplierName',
label: '供应商',
},
{
prop: 'remark',
label: '备注',
},
];
export default {
mixins: [basicPage, tableHeightMixin],
name: '',
components: {
AddOrUpdate,
Treeselect,
},
data() {
return {
//
treeName: undefined,
deptOptions: undefined,
deptOptions1: undefined,
treeLoading: false,
defaultProps: {
children: 'children',
label: 'name',
},
//
title: '',
//
open: false,
//
form: {
id: undefined,
parentId: undefined,
name: undefined,
defaultType: false,
},
//
rules: {
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
},
urlOptions: {
getDataListURL: getProductMaterialPage,
deleteURL: deleteProductMaterial,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:core-product:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:core-product:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableData: [],
formConfig: [
{
type: 'input',
label: '物料产品名称',
placeholder: '物料产品名称',
param: 'name',
},
{
type: 'input',
label: '物料产品编号',
placeholder: '物料产品编号',
param: 'code',
},
{
type: 'input',
label: '物料产品类型',
param: 'type',
disabled: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:material:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
};
},
watch: {
//
treeName(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getDataList();
this.getTreeselect();
},
methods: {
//
deleteHandle(id, name, index) {
this.$confirm(`是否确认删除物料产品名称为"${name}"的数据项`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
})
.catch(() => {});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.name = val.name ? val.name : undefined;
this.listQuery.code = val.code ? val.code : undefined;
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init();
this.$refs.addOrUpdate.typeId(
this.listQuery.typeId,
this.listQuery.product
);
});
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
/** 树操作 */
//
getTreeselect() {
this.treeLoading = true;
getMaterialTree().then((response) => {
// treeArr[0].push(...this.handleTree(response.data, 'id'));
// deptOptions
this.deptOptions = [];
this.treeLoading = false;
this.deptOptions.push(...this.handleTree(response.data, 'id'));
const arr = [{ name: '全部', parentId: -1 }];
this.deptOptions1 = arr.concat(this.deptOptions);
});
},
//
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
//
handleNodeClick(data) {
this.listQuery.typeId = data.id || undefined;
this.listQuery.product = data.product;
this.$refs.searchBarForm.formInline.type = data.name || undefined;
},
//
append(data) {
this.open = true;
this.title = '新增物料产品类型';
this.form.id = undefined;
this.form.parentId = data.id;
},
//
remove(node, data) {
this.$confirm(`是否确认删除名称为"${data.name}"的数据项`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
deleteMaterialTree(data.id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getTreeselect();
},
});
});
})
.catch(() => {});
},
//
edit(node, data) {
this.open = true;
this.title = '编辑物料产品类型';
this.form.id = data.id;
this.form.name = data.name;
this.form.parentId = data.parentId;
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children,
};
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: undefined,
parentId: 0,
name: undefined,
defaultType: false,
};
this.resetForm('form');
},
//
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.form.id) {
updateMaterialTree(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.cancel();
this.getTreeselect();
});
return;
}
//
createMaterialTree(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.cancel();
this.getTreeselect();
});
});
},
},
};
</script>
<style scoped>
.btnHover:hover {
color: #67c23a;
transform: scale(1.5);
}
</style>

View File

@ -0,0 +1,108 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-08-05 16:12:58
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料名称" prop="materialId">
<el-select
v-model="dataForm.materialId"
placeholder="请选择物料"
@change="setMaterialCode"
style="width: 100%">
<el-option
v-for="dict in materialList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
disabled
placeholder="请输入物料编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="批次号" prop="code">
<el-input v-model="dataForm.code" clearable placeholder="请输入批次号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="批次名称" prop="name">
<el-input v-model="dataForm.name" clearable placeholder="请输入批次名称" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-form>
</template>
<script>
import basicAdd from '../mixins/basic-add';
import { createMaterialDate, updateMaterialDate, getMaterialDate, getCode } from "@/api/base/materialDate";
import { getMaterialList } from "@/api/base/material";
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: false,
codeURL: getCode,
createURL: createMaterialDate,
updateURL: updateMaterialDate,
infoURL: getMaterialDate,
},
dataForm: {
id: undefined,
code: undefined,
name: undefined,
materialId: undefined,
materialCode: undefined,
remark: undefined,
},
materialList: [],
dataRule: {
materialId: [{ required: true, message: "物料不能为空", trigger: "blur" }],
code: [{ required: true, message: "批次号不能为空", trigger: "blur" }],
name: [{ required: true, message: "批次名称不能为空", trigger: "blur" }],
}
};
},
mounted() {
this.getDict()
console.log('我看看', this.dataForm)
},
methods: {
async getDict() {
//
const res = await getMaterialList();
this.materialList = res.data;
},
setMaterialCode() {
const chooseM = this.materialList.filter(item => {
return item.id === this.dataForm.materialId
})
this.dataForm.materialCode = chooseM[0].code
}
},
};
</script>

View File

@ -0,0 +1,190 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="40%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../mixins/basic-page';
import { parseTime } from '../mixins/code-filter';
import {
getMaterDatePage,
deleteMaterialDate
} from '@/api/base/materialDate';
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime
},
{
prop: 'code',
label: '批次号'
},
{
prop: 'name',
label: '批次名称'
},
{
prop: 'materialCode',
label: '物料编码'
},
{
prop: 'materialName',
label: '物料名称'
},
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getMaterDatePage,
deleteURL: deleteMaterialDate,
// exportURL: exportFactoryExcel,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:material-date:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:material-date:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'input',
label: '批次名',
placeholder: '批次名',
param: 'name',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:material-date:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true
},
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
//
getDataList() {
this.dataListLoading = true;
this.urlOptions.getDataListURL(this.listQuery).then(response => {
this.tableData = response.data.records;
this.listQuery.total = response.data.total;
this.dataListLoading = false;
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.name = val.name ? val.name : undefined;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 10,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
//
deleteHandle(id, name, index) {
this.$confirm(`是否删除物料批次名称为"${name}"的数据项?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
})
.catch(() => { });
}
},
};
</script>

View File

@ -0,0 +1,65 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 15:27:31
* @LastEditors: zwq
* @LastEditTime: 2023-08-01 16:25:54
* @Description:
-->
<template>
<div :class="[className, { 'p-0': noPadding }]">
<slot />
</div>
</template>
<script>
export default {
props: {
size: {
// : xl lg md sm
type: String,
default: 'de',
validator: function (val) {
return ['xl', 'lg', 'de', 'md', 'sm'].indexOf(val) !== -1;
},
},
noPadding: {
type: Boolean,
default: false,
},
},
computed: {
className: function () {
return `${this.size}-title`;
},
},
};
</script>
<style lang="scss" scoped>
$pxls: (xl, 28px) (lg, 24px) (de, 20px) (md, 18px) (sm, 16px);
$mgr: 8px;
@each $size, $height in $pxls {
.#{$size}-title {
font-size: 18px;
line-height: $height;
color: #000;
font-weight: 500;
font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
&::before {
content: '';
display: inline-block;
vertical-align: top;
width: 4px;
height: $height + 2px;
border-radius: 1px;
margin-right: $mgr;
background-color: #0b58ff;
}
}
}
.p-0 {
padding: 0;
}
</style>

View File

@ -0,0 +1,420 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-08-08 16:47:36
* @Description:
-->
<template>
<el-drawer
:visible.sync="visible"
:show-close="false"
:wrapper-closable="isdetail"
class="drawer"
size="70%">
<small-title slot="title" :no-padding="true">
{{ isdetail ? '详情' : !dataForm.id ? '新增' : '编辑' }}
</small-title>
<div class="content">
<div class="visual-part">
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="产品名称" prop="productId">
<el-select
v-model="dataForm.productId"
filterable
clearable
:disabled="isdetail"
style="width: 100%"
placeholder="请选择产品">
<el-option
v-for="dict in productList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品BOM编码" prop="code">
<el-input
v-model="dataForm.code"
:disabled="isdetail"
placeholder="请输入产品Bom编码" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
:disabled="isdetail"
clearable
placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div class="attr-list" v-if="idAttrShow">
<small-title
style="margin: 16px 0; padding-left: 8px"
:no-padding="true">
BOM明细
</small-title>
<div v-if="!isdetail" class="action_btn">
<template>
<span style="display: inline-block">
<el-button type="text" @click="addNew()" icon="el-icon-plus">
添加
</el-button>
</span>
</template>
</div>
<base-table
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData">
<method-btn
v-if="!isdetail"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
v-show="listQuery.total > 0"
:total="listQuery.total"
:page.sync="listQuery.pageNo"
:limit.sync="listQuery.pageSize"
:page-sizes="[5, 10, 15]"
@pagination="getList" />
</div>
<div v-if="!isdetail" class="drawer-body__footer">
<el-button style="" @click="goback()">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</div>
</div>
<attr-add
v-if="addOrUpdateVisible"
ref="addOrUpdate"
:bom-id="dataForm.id"
@refreshDataList="getList" />
</el-drawer>
</template>
<script>
import basicAdd from '../mixins/basic-add';
import {
createMaterialPB,
updateMaterialPB,
getMaterialPB,
getCode,
getProBomList,
createMaterialPBDet,
updateMaterialPBDet,
deleteMaterialPBDet,
} from '@/api/base/materialProductBom';
import { getMaterialTree, getMaterialList } from '@/api/base/material';
import SmallTitle from './SmallTitle';
import { parseTime } from '../mixins/code-filter';
import attrAdd from './attr-add';
import { publicFormatter } from '@/utils/dict';
const tableBtn = [
{
type: 'edit',
btnName: '编辑',
},
{
type: 'delete',
btnName: '删除',
},
];
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime,
width: 160,
},
{
prop: 'materialName',
label: '物料名称',
showOverflowtooltip: true,
},
{
prop: 'materialCode',
label: '物料编码',
width: 160,
},
{
prop: 'unit',
label: '单位',
filter: publicFormatter('unit_dict'),
width: 60,
},
{
prop: 'num',
label: '数量',
width: 60,
},
{
prop: 'remark',
label: '备注',
},
];
export default {
mixins: [basicAdd],
components: { SmallTitle, attrAdd },
data() {
return {
tableBtn,
tableProps,
addOrUpdateVisible: false,
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createMaterialPB,
updateURL: updateMaterialPB,
infoURL: getMaterialPB,
},
listQuery: {
pageSize: 10,
pageNo: 1,
total: 0,
},
dataForm: {
id: undefined,
code: undefined,
productId: '',
remark: undefined,
},
productList: [],
materialAttrList: [],
tableData: [],
visible: false,
isdetail: false,
idAttrShow: false,
dataRule: {
productId: [
{ required: true, message: '产品不能为空', trigger: 'blur' },
],
},
};
},
mounted() {
this.getDict();
},
methods: {
handleClick(raw) {
if (raw.type === 'delete') {
this.deleteDetail(raw.data);
} else {
this.addNew(raw.data.id);
}
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.dataForm.id) {
this.urlOptions.updateURL(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
this.urlOptions.createURL(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
// this.visible = false;
this.idAttrShow = true;
this.dataForm.id = response.data;
this.$emit('refreshDataList');
});
});
},
async getDict() {
const materRes = await getMaterialTree();
let typeId = materRes.data[0].product
? materRes.data[0].id
: materRes.data[1].id;
const listQuery = {
typeId: typeId,
};
const materData = await getMaterialList(listQuery);
this.productList = [];
this.productList = materData.data;
},
initData() {
// this.materialAttrList.splice(0);
this.listQuery.total = 0;
},
deleteDetail(raw) {
this.$confirm(
`是否确认删除物料名称为"${raw.materialName}"的数据项?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
deleteMaterialPBDet(raw.id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getList();
},
});
});
})
.catch(() => {});
},
getList() {
// Bom
getProBomList({
...this.listQuery,
bomId: this.dataForm.id,
}).then((response) => {
this.tableData = response.data.records;
this.listQuery.total = response.data.total;
});
},
//
addRow() {
const row = {
bomId: this.dataForm.id,
materialId: '',
num: 0,
materialCode: undefined,
unit: undefined,
remark: '',
isEdit: true,
};
this.tableData.push(row);
},
init(id, isdetail) {
this.initData();
this.isdetail = isdetail || false;
this.dataForm.id = id || undefined;
this.visible = true;
if (id) {
this.idAttrShow = true;
} else {
this.idAttrShow = false;
}
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
//
this.urlOptions.infoURL(id).then((response) => {
this.dataForm = response.data;
});
// Bom
this.getList();
} else {
if (this.urlOptions.isGetCode) {
this.getCode();
}
}
});
},
goback() {
this.$emit('refreshDataList');
this.visible = false;
// this.initData();
},
goEdit() {
this.isdetail = false;
},
// /
addNew(id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
},
},
};
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
display: flex;
flex-direction: column;
}
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
}
.drawer >>> .el-drawer__body {
flex: 1;
height: 1px;
display: flex;
flex-direction: column;
}
.drawer >>> .content {
padding: 30px 24px;
flex: 1;
display: flex;
flex-direction: column;
/* height: 100%; */
}
.drawer >>> .visual-part {
flex: 1 auto;
max-height: 20vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */
}
.drawer >>> .el-form,
.drawer >>> .attr-list {
padding: 0 16px;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
.action_btn {
float: right;
margin: -40px 15px;
font-size: 14px;
}
.add {
color: #0b58ff;
}
</style>

View File

@ -0,0 +1,203 @@
<template>
<el-dialog
:visible.sync="visible"
:width="'40%'"
:append-to-body="true"
:close-on-click-modal="false"
class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">
{{ !dataForm.id ? '新增' : '编辑' }}
</div>
</slot>
</template>
<el-form
ref="dataForm"
:model="dataForm"
:rules="dataRule"
label-width="80px"
@keyup.enter.native="dataFormSubmit()">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料名称" prop="materialId">
<el-select
v-model="dataForm.materialId"
placeholder="请选择物料"
clearable
filterable
@change="setCode"
style="width: 100%"
>
<el-option
v-for="dict in materialList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
clearable
disabled
placeholder="请输入物料编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="单位" prop="unit">
<el-select
v-model="dataForm.unit"
style="width: 100%"
disabled
placeholder="请选择单位">
<el-option
v-for="dict in getDictDatas(DICT_TYPE.UNIT_DICT)"
:key="dict.value"
:label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数量" prop="num">
<el-input-number v-model="dataForm.num" controls-position="right" clearable placeholder="请输入数量" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-form>
<el-row style="text-align: right">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</el-row>
</el-dialog>
</template>
<script>
import { getMaterialTree,getMaterialList } from '@/api/base/material';
import { createMaterialPBDet, updateMaterialPBDet, getMaterialPBDet } from "@/api/base/materialProductBom";
export default {
props: {
bomId: {
type: String,
default: '',
},
},
data() {
return {
visible: false,
dataForm: {
id: undefined,
materialId: '',
num: 0,
materialCode: undefined,
unit: undefined,
remark: '',
},
materialList: [],
dataRule: {
materialId: [{ required: true, message: '物料名称不能为空', trigger: 'change' }],
num: [{ required: true, message: '数量不能为空', trigger: 'blur' }]
},
};
},
mounted() {
this.getDict()
},
methods: {
async getDict() {
//
const materRes = await getMaterialTree();
let typeId = materRes.data[0].product?materRes.data[1].id:materRes.data[0].id
const listQuery= {
typeId:typeId
}
const materData = await getMaterialList(listQuery);
this.materialList = [];
this.materialList = materData.data;
},
init(id) {
this.dataForm.id = id || '';
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
getMaterialPBDet(this.dataForm.id).then((res) => {
this.dataForm = res.data
this.setCode()
});
}
});
},
setCode() {
const tempMaterial = this.materialList.filter(item =>{
return item.id === this.dataForm.materialId
})
this.dataForm.materialCode = tempMaterial[0]?.code
this.dataForm.unit = tempMaterial[0].unit === undefined ? undefined : String(tempMaterial[0]?.unit)
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
//
if (this.dataForm.id) {
updateMaterialPBDet({
...this.dataForm,
bomId: this.bomId,
}).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
createMaterialPBDet({
...this.dataForm,
bomId: this.bomId,
}).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
});
}
});
},
},
};
</script>
<style scoped>
.dialog >>> .el-dialog__body {
padding: 30px 24px;
}
.dialog >>> .el-dialog__header {
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
padding: 13px 24px;
border-bottom: 1px solid #e9e9e9;
}
.dialog >>> .el-dialog__header .titleStyle::before {
content: '';
display: inline-block;
width: 4px;
height: 16px;
background-color: #0b58ff;
border-radius: 1px;
margin-right: 8px;
position: relative;
top: 2px;
}
</style>

View File

@ -0,0 +1,182 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:max-height="tableH"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<add-or-update
v-if="addOrUpdateVisible"
ref="addOrUpdate"
@refreshDataList="getDataList" />
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../mixins/basic-page';
// import { parseTime } from '../mixins/code-filter';
import {
getMaterialPBPage,
deleteMaterialPB
} from '@/api/base/materialProductBom';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [
{
prop: 'productName',
label: '产品名称'
},
{
prop: 'code',
label: '产品BOM编码'
},
{
prop: 'remark',
label: '备注'
}
];
export default {
mixins: [basicPage, tableHeightMixin],
components: {
AddOrUpdate,
},
data() {
return {
urlOptions: {
getDataListURL: getMaterialPBPage,
deleteURL: deleteMaterialPB
// exportURL: exportFactoryExcel,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:material-product-bom:queryMaterial`)
? {
type: 'detail',
btnName: '查看物料',
}
: undefined,
this.$auth.hasPermi(`base:material-product-bom:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
// this.$auth.hasPermi(`base:material-product-bom:editMaterial`)
// ? {
// type: 'editMaterial',
// btnName: '',
// }
// : undefined,
this.$auth.hasPermi(`base:material-product-bom:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'input',
label: '产品名称',
placeholder: '产品名称',
param: 'name',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:material:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true
},
],
};
},
created() {},
methods: {
otherMethods(val) {
if (val.type === 'detail') {
this.addOrUpdateVisible = true;
this.addOrEditTitle = '详情';
this.$nextTick(() => {
this.$refs.addOrUpdate.init(val.data.id, true);
});
} else {
this.addOrEditTitle = '编辑';
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(val.data.id);
});
}
},
//
getDataList() {
this.dataListLoading = true;
this.urlOptions.getDataListURL(this.listQuery).then(response => {
this.tableData = response.data.records;
this.listQuery.total = response.data.total;
this.dataListLoading = false;
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.productName = val.name ? val.name : undefined;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 20,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -0,0 +1,284 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-08-05 16:13:52
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px"
label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="物料名称" prop="materialId">
<el-select
v-model="dataForm.materialId"
placeholder="请选择物料"
clearable
filterable
@change="setCode"
style="width: 100%">
<el-option
v-for="dict in materialList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
clearable
disabled
placeholder="请输入物料编码" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="物料批次" prop="materialDateId">
<el-select
v-model="dataForm.materialDateId"
clearable
filterable
placeholder="请选择物料批次"
style="width: 100%">
<el-option
v-for="dict in materialDateList"
:key="dict.id"
:label="dict.code"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="使用设备" prop="equipmentId">
<el-select
v-model="dataForm.equipmentId"
clearable
filterable
placeholder="请选择使用设备"
style="width: 100%">
<el-option
v-for="dict in eqList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="使用时间" prop="useTime">
<el-date-picker
v-model="dataForm.useTime"
type="datetime"
format="yyyy-MM-dd HH:mm:ss"
value-format="timestamp"
placeholder="选择日期时间" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="操作员" prop="userNames">
<el-select
v-model="dataForm.userNames"
clearable
filterable
multiple
placeholder="请选择操作员"
style="width: 100%">
<el-option
v-for="dict in workersList"
:key="dict.id"
:label="dict.nickname"
:value="dict.nickname" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="使用数量" prop="num">
<el-input-number
v-model="dataForm.num"
clearable
controls-position="right"
placeholder="请输入使用数量"
style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数据来源" prop="source">
<el-select
v-model="dataForm.source"
clearable
placeholder="请选择数据来源">
<el-option
v-for="dict in this.dataSourceList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
clearable
placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../mixins/basic-add';
import {
createMaterialLog,
updateMaterialLog,
getMaterialLog,
getEqListAll,
} from '@/api/base/materialUseLog';
import { getMaterialTree,getMaterialList } from '@/api/base/material';
import { getMaterDateList } from '@/api/base/materialDate';
import { listSimpleUsers } from '@/api/system/user';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: createMaterialLog,
updateURL: updateMaterialLog,
infoURL: getMaterialLog,
},
dataForm: {
id: undefined,
materialId: undefined,
materialCode: undefined,
materialDateId: undefined,
equipmentId: undefined,
userName: undefined,
userNames: [],
useTime: new Date().getTime(),
address: undefined,
num: 0,
source: undefined,
remark: undefined,
},
dataSourceList: [
{
id: 1,
name: '手动',
},
{
id: 2,
name: 'PDA',
},
],
materialList: [],
materialDateList: [],
eqList: [],
workersList: [],
dataRule: {
materialId: [
{ required: true, message: '物料不能为空', trigger: 'blur' },
],
useTime: [
{ required: true, message: '使用时间不能为空', trigger: 'blur' },
],
userNames: [
{ required: true, message: '操作员不能为空', trigger: 'blur' },
],
num: [{ required: true, message: '使用数量不能为空', trigger: 'blur' }],
},
};
},
mounted() {
this.getDictData();
},
methods: {
async getDictData() {
const materRes = await getMaterialTree();
let typeId = materRes.data[0].product?materRes.data[1].id:materRes.data[0].id
const listQuery= {
typeId:typeId
}
const materData = await getMaterialList(listQuery);
this.materialList = [];
this.materialList = materData.data;
const dateRes = await getMaterDateList();
this.materialDateList = dateRes.data;
const eqRes = await getEqListAll();
this.eqList = eqRes.data;
const workerRes = await listSimpleUsers();
this.workersList = workerRes.data;
},
//
dataFormSubmit() {
this.dataForm.userName = this.dataForm.userNames.join(',');
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.dataForm.id) {
this.urlOptions.updateURL(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
this.urlOptions.createURL(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
});
});
},
init(id) {
this.dataForm.id = id || undefined;
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
this.urlOptions.infoURL(id).then((response) => {
this.dataForm.id = response.data.id;
this.dataForm.materialCode = response.data.materialCode;
this.dataForm.materialId = response.data.materialId;
this.dataForm.materialDateId = response.data.materialDateId;
this.dataForm.equipmentId = response.data.equipmentId;
this.dataForm.useTime = response.data.useTime;
// this.dataForm.userName = response.data.userName
this.dataForm.num = response.data.num;
this.dataForm.source = response.data.source;
this.dataForm.remark = response.data.remark;
this.dataForm.userNames = response.data.userName.split(',');
});
} else {
}
});
},
setCode() {
const tempMaterial = this.materialList.filter((item) => {
return item.id === this.dataForm.materialId;
});
this.dataForm.materialCode = tempMaterial[0].code;
getMaterDateList({ materialId: this.dataForm.materialId }).then((res) => {
this.materialDateList = res.data;
});
},
},
};
</script>

View File

@ -0,0 +1,250 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:max-height="tableH"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="60%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../mixins/basic-page';
import { parseTime } from '../mixins/code-filter';
import {
getMaterialLogPage,
deleteMaterialLog
} from '@/api/base/materialUseLog';
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [
{
prop: 'materialName',
label: '物料名称'
},
{
prop: 'materialCode',
label: '物料编码',
width: 160,
},
{
prop: 'materialDateName',
label: '物料批次'
},
{
prop: 'equipName',
label: '使用设备'
},
{
prop: 'num',
label: '使用数量'
},
{
prop: 'useTime',
label: '使用时间',
filter: parseTime,
width: 160,
},
{
prop: 'userName',
label: '操作人',
showOverflowtooltip: true,
},
{
prop: 'source',
label: '数据来源',
filter: (val) => ['未知', '手动', '自动'][val],
width: 80,
},
{
prop: 'remark',
label: '备注'
}
];
export default {
mixins: [basicPage, tableHeightMixin],
data() {
return {
urlOptions: {
getDataListURL: getMaterialLogPage,
deleteURL: deleteMaterialLog,
// exportURL: exportFactoryExcel,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:material-use-log:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:material-use-log:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
listQuery: {
pageSize: 20,
pageNo: 1,
total: 1,
materialName: undefined,
useTime: []
},
formConfig: [
{
type: 'input',
label: '物料名称',
placeholder: '物料名称',
param: 'name',
},
{
type: 'datePicker',
label: '使用时间段',
dateType: 'datetimerange',
format: 'yyyy-MM-dd HH:mm:ss',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
width: 350,
param: 'time',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary'
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:material-use-log:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true
},
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
//
getDataList() {
this.dataListLoading = true;
this.urlOptions.getDataListURL(this.listQuery).then(response => {
this.tableData = response.data.records;
this.listQuery.total = response.data.total;
this.dataListLoading = false;
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.materialName = val.name ? val.name : undefined;
if (val.time) {
this.listQuery.useTime[0] = val.time[0]
this.listQuery.useTime[1] = val.time[1]
} else {
this.listQuery.useTime = []
}
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 20,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
//tableBtn
handleClick(val) {
if (val.type === "edit") {
this.addOrUpdateVisible = true;
this.addOrEditTitle = "编辑";
this.$nextTick(() => {
this.$refs.addOrUpdate.init(val.data.id);
});
} else if (val.type === "delete") {
this.deleteHandle(val.data.id, val.data.materialName)
} else if (val.type === "change") {
this.changeStatus(val.data.id)
} else {
this.otherMethods(val)
}
},
//
deleteHandle(id, name) {
this.$modal
.delConfirm(name ? '名称: ' + name : '序号: ' + index).then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
})
.catch(() => { });
}
},
};
</script>

View File

@ -0,0 +1,100 @@
/*
* @Author: zwq
* @Date: 2022-08-24 11:19:43
* @LastEditors: zwq
* @LastEditTime: 2023-08-03 14:21:04
* @Description:
*/
export default {
data() {
/* eslint-disable */
return {
urlOptions: {
createURL: '',
updateURL: '',
infoURL: '',
codeURL: '',
getOption: false,
isGetCode: false,
optionArrUrl: [],
optionArr: {}
},
visible: false,
setData: false
}
},
created() {
},
activated() {
},
methods: {
init(id) {
this.dataForm.id = id || "";
this.visible = true;
if (this.urlOptions.getOption) {
this.getArr()
}
this.$nextTick(() => {
this.$refs["dataForm"].resetFields();
if (this.dataForm.id) {
this.urlOptions.infoURL(id).then(response => {
this.dataForm = response.data;
if (this.setData) {
this.setDataForm()
}
});
} else {
if (this.urlOptions.isGetCode) {
this.getCode()
}
}
});
},
getCode() {
this.urlOptions.codeURL()
.then(({ data: res }) => {
this.dataForm.code = res;
})
.catch(() => {});
},
getArr() {
const params = {
pageSize: 100,
pageNo: 1,
}
this.urlOptions.optionArrUrl.forEach((item, index) => {
item(params).then(({ data: res }) => {
this.$set(this.urlOptions.optionArr, `arr${index}`, res.list)
})
.catch(() => {
});
});
},
// 表单提交
dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => {
if (!valid) {
return false;
}
// 修改的提交
if (this.dataForm.id) {
this.urlOptions.updateURL(this.dataForm).then(response => {
this.$modal.msgSuccess("修改成功");
this.visible = false;
this.$emit("refreshDataList");
});
return;
}
// 添加的提交
this.urlOptions.createURL(this.dataForm).then(response => {
this.$modal.msgSuccess("新增成功");
this.visible = false;
this.$emit("refreshDataList");
});
});
},
formClear() {
this.$refs.dataForm.resetFields()
}
}
}

View File

@ -0,0 +1,165 @@
/*
* @Author: zwq
* @Date: 2022-08-24 11:19:43
* @LastEditors: zwq
* @LastEditTime: 2024-08-05 16:35:15
* @Description:
*/
export default {
data() {
/* eslint-disable */
return {
urlOptions: {
getDataListURL: '',
deleteURL: '',
statusUrl: '',
exportURL: ''
},
tableData: [],
listQuery: {
pageSize: 20,
pageNo: 1,
total: 1,
},
exportLoading: false,
dataListLoading: false,
addOrEditTitle: '',
addOrUpdateVisible: false,
}
},
created() {
},
mounted() {
this.getDataList()
},
methods: {
// 获取数据列表
getDataList() {
this.dataListLoading = true;
this.urlOptions.getDataListURL(this.listQuery).then(response => {
this.tableData = response.data.list;
this.listQuery.total = response.data.total;
this.dataListLoading = false;
});
},
// 每页数
sizeChangeHandle(val) {
this.listQuery.pageSize = val;
this.listQuery.pageNo = 1;
this.getDataList();
},
// 当前页
currentChangeHandle(val) {
this.listQuery.pageNo = val;
this.getDataList();
},
// 新增 / 修改
addOrUpdateHandle(id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
},
cancel(id) {
this.$refs["popover-" + id].showPopper = false;
},
//改变状态
changeStatus(id) {
this.$http
.post(this.urlOptions.statusUrl, { id })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg);
}
this.$refs["popover-" + id].showPopper = false;
this.$message({
message: this.$t("prompt.success"),
type: "success",
duration: 500,
onClose: () => {
this.getDataList();
},
});
})
.catch(() => { });
},
//tableBtn点击
handleClick(val) {
if (val.type === "edit") {
this.addOrUpdateVisible = true;
this.addOrEditTitle = "编辑";
this.$nextTick(() => {
this.$refs.addOrUpdate.init(val.data.id);
});
} else if (val.type === "delete") {
this.deleteHandle(val.data.id, val.data.name, val.data._pageIndex)
} else if (val.type === "change") {
this.changeStatus(val.data.id)
} else {
this.otherMethods(val)
}
},
// 删除
deleteHandle(id, name, index) {
this.$modal
.delConfirm(name ? '名称: ' + name : '序号: ' + index)
.then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
})
.catch(() => { });
},
//search-bar点击
buttonClick(val) {
switch (val.btnName) {
case "search":
this.listQuery.xm1 = val.xm1;
this.listQuery.xm2 = val.xm2;
this.listQuery.pageNo = 1;
this.getDataList();
break;
case "add":
this.addOrEditTitle = '新增'
this.addOrUpdateVisible = true;
this.addOrUpdateHandle()
break;
default:
console.log(val)
}
},
handleCancel() {
this.$refs.addOrUpdate.formClear()
this.addOrUpdateVisible = false
this.addOrEditTitle = ''
},
handleConfirm() {
this.$refs.addOrUpdate.dataFormSubmit()
},
successSubmit() {
this.handleCancel()
this.getDataList()
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal.confirm('是否确认导出所有数据项?').then(() => {
this.exportLoading = true;
return this.urlOptions.exportURL(params);
}).then(response => {
this.$download.excel(response, '工厂.xls');
this.exportLoading = false;
}).catch(() => { });
}
}
}

View File

@ -0,0 +1,85 @@
/*
* @Date: 2020-12-29 16:49:28
* @LastEditors: zwq
* @LastEditTime: 2024-07-08 16:27:39
* @FilePath: \basic-admin\src\filters\basicData\index.js
* @Description:
*/
const table = {
lineStatus: {
1: '生产中',
2: '停止',
3: '未知',
},
reportType: {
1: '日',
2: '周',
3: '月'
}
}
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.\d{3}/gm), '');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
// 遍历树结构返回数组
export function getTreeArr(arr) {
let result =[]
arr.forEach(item => {
if(item.children && item.children.length>0){
let {children,...obj} = item
result.push(obj)
result = result.concat(getTreeArr(children))
}else{
let {children,...obj} = item
result.push(obj)
}
});
return result
}
export default function (dictTable) {
return function (val) {
return table?.[dictTable]?.[val]
}
}

View File

@ -70,7 +70,7 @@ export default {
}; };
}, },
mounted() { mounted() {
this.getList(); // this.getList();
}, },
methods: { methods: {
/** 查询列表 */ /** 查询列表 */

View File

@ -24,7 +24,7 @@ export default {
}, },
data() { data() {
return { return {
heightNum: 200, heightNum: 236,
nameData: [], nameData: [],
list: [], list: [],
}; };

View File

@ -45,7 +45,7 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.currentDataContainer { .currentDataContainer {
width: 100%; width: 100%;
min-height: calc(100vh - 120px - 8px); min-height: calc(100vh - 164px);
background: rgba(242, 244, 249, 1); background: rgba(242, 244, 249, 1);
.topBox { .topBox {
.el-menu { .el-menu {
@ -79,10 +79,11 @@ export default {
} }
} }
.bottomBox { .bottomBox {
min-height: calc(100vh - 184px); height: calc(100vh - 220px);
background: #fff; background: #fff;
padding: 16px; padding: 16px;
border-radius: 8px; border-radius: 8px;
overflow-y: auto;
} }
} }
</style> </style>

View File

@ -48,7 +48,7 @@
</div> </div>
</div> </div>
<!-- side bar --> <!-- side bar -->
<div class="side-bar__left" style="width: 240px; height: 100%"> <div class="side-bar__left">
<el-tree <el-tree
class="custom-tree-class" class="custom-tree-class"
:data="currentFactory?.children" :data="currentFactory?.children"
@ -87,6 +87,7 @@
:table-props="table.tableProps" :table-props="table.tableProps"
:table-data="table.dataManager?.dataList ?? []" :table-data="table.dataManager?.dataList ?? []"
:span-method="spanMethod" :span-method="spanMethod"
:max-height="tableH"
@emitFun="(val) => handleEmitFun(table, val)"></base-table> @emitFun="(val) => handleEmitFun(table, val)"></base-table>
<pagination <pagination
:key="table.key + '__pagination'" :key="table.key + '__pagination'"
@ -115,9 +116,11 @@
<script> <script>
// import Graph from './graph.vue'; // import Graph from './graph.vue';
import { getWorkOrderList, getTreeData } from '@/api/quality/deviceParameters'; import { getWorkOrderList, getTreeData } from '@/api/quality/deviceParameters';
import tableHeightMixin from '@/mixins/tableHeightMixin';
export default { export default {
name: 'EquipmentProcessAmount', name: 'EquipmentProcessAmount',
// components: { Graph }, // components: { Graph },
mixins: [tableHeightMixin],
props: {}, props: {},
data() { data() {
const now = new Date(); const now = new Date();
@ -578,6 +581,10 @@ export default {
</script> </script>
<style scoped> <style scoped>
.side-bar__left {
width: 240px;
height: calc(100% - 70px);
}
.side-bar__left >>> .is-current { .side-bar__left >>> .is-current {
padding: 0; padding: 0;
color: #111; color: #111;

View File

@ -81,7 +81,7 @@ export default {
mixins: [tableHeightMixin], mixins: [tableHeightMixin],
data() { data() {
return { return {
heightNum: 220, heightNum: 256,
tableProps, tableProps,
tableBtn: [ tableBtn: [
this.$auth.hasPermi(`base:packaging-print-log:update`) this.$auth.hasPermi(`base:packaging-print-log:update`)

View File

@ -0,0 +1,38 @@
<template>
<div>
<span class="dot" :class="injectData.status === 1 ? 'red' : 'green'"></span>
<span>{{ state }}</span>
</div>
</template>
<script>
export default {
name: "StatusBtn",
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
computed: {
state() {
return this.injectData.status === 1 ? "停用" : "启用";
},
},
};
</script>
<style scoped>
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 3px;
vertical-align: middle;
margin-right: 8px;
}
.green {
background: #10dc76;
}
.red {
background: #ff5656;
}
</style>

View File

@ -0,0 +1,38 @@
<template>
<div>
<span class="dot" :class="injectData.status === 1 ? 'red' : 'green'"></span>
<span>{{ state }}</span>
</div>
</template>
<script>
export default {
name: "StatusBtn2",
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
computed: {
state() {
return this.injectData.status === 1 ? "关闭" : "开启";
},
},
};
</script>
<style scoped>
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 3px;
vertical-align: middle;
margin-right: 8px;
}
.green {
background: #10dc76;
}
.red {
background: #ff5656;
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<div>
<span
class="dot"
:class="injectData.resultCode === 0 ? 'green' : 'red'"
></span>
<span>{{ state }}</span>
</div>
</template>
<script>
export default {
name: "StatusBtn3",
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
computed: {
state() {
return this.injectData.resultCode === 0 ? "成功" : "失败";
},
},
};
</script>
<style scoped>
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 3px;
vertical-align: middle;
margin-right: 8px;
}
.green {
background: #10dc76;
}
.red {
background: #ff5656;
}
</style>

View File

@ -0,0 +1,38 @@
<template>
<div>
<span class="dot" :class="injectData.result === 0 ? 'green' : 'red'"></span>
<span>{{ state }}</span>
</div>
</template>
<script>
export default {
name: "StatusBtn3",
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
computed: {
state() {
return this.injectData.result === 0 ? "成功" : "失败";
},
},
};
</script>
<style scoped>
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 3px;
vertical-align: middle;
margin-right: 8px;
}
.green {
background: #10dc76;
}
.red {
background: #ff5656;
}
</style>

View File

@ -0,0 +1,39 @@
<template>
<el-switch
v-model="status"
type="text"
size="small"
@change="changeHandler"
/>
</template>
<script>
export default {
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
data() {
return {
status: false,
};
},
mounted() {
this.mapToState();
},
methods: {
mapToState() {
this.status = this.injectData.status === 0 ? true : false;
},
changeHandler() {
let params = {};
params.id = this.injectData.id;
params.status = this.status ? "0" : "1";
params.username = this.injectData.username;
this.$emit("emitData", params);
},
},
};
</script>

View File

@ -0,0 +1,162 @@
<template>
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.name" :disabled="true" />
</el-form-item>
<el-form-item label="角色标识">
<el-input v-model="form.code" :disabled="true" />
</el-form-item>
<el-form-item label="权限范围">
<el-select v-model="form.dataScope" style="width: 100%">
<el-option
v-for="item in dataScopeDictDatas"
:key="parseInt(item.value)"
:label="item.label"
:value="parseInt(item.value)"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label="数据权限"
v-show="form.dataScope === SysDataScopeEnum.DEPT_CUSTOM"
>
<el-checkbox
:checked="!form.deptCheckStrictly"
@change="handleCheckedTreeConnect($event, 'dept')"
>父子联动(选中父节点自动选择子节点)</el-checkbox
>
<el-checkbox
v-model="deptExpand"
@change="handleCheckedTreeExpand($event, 'dept')"
>展开/折叠</el-checkbox
>
<el-checkbox
v-model="deptNodeAll"
@change="handleCheckedTreeNodeAll($event, 'dept')"
>全选/全不选</el-checkbox
>
<el-tree
class="tree-border"
:data="deptOptions"
show-checkbox
default-expand-all
ref="dept"
node-key="id"
:check-strictly="form.deptCheckStrictly"
empty-text="加载中,请稍后"
:props="defaultProps"
></el-tree>
</el-form-item>
</el-form>
</template>
<script>
import { SystemDataScopeEnum } from "@/utils/constants";
import { getRole } from "@/api/system/role";
import { listSimpleDepts } from "@/api/system/dept";
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
import { assignRoleDataScope } from "@/api/system/permission";
export default {
name: "DataAuth",
data() {
return {
form: {
id: undefined,
name: undefined,
code: undefined,
deptIds: [],
dataScope: undefined,
deptCheckStrictly: false,
},
deptExpand: true,
deptNodeAll: false,
//
deptOptions: [], //
depts: [], //
defaultProps: {
label: "name",
children: "children",
},
//
SysDataScopeEnum: SystemDataScopeEnum,
//
dataScopeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_DATA_SCOPE),
};
},
methods: {
init(id) {
this.form.id = id;
getRole(id).then((res) => {
this.form.name = res.data.name;
this.form.code = res.data.code;
this.form.dataScope = res.data.dataScope;
//
listSimpleDepts().then((response) => {
// deptOptions
this.deptOptions = [];
this.deptOptions.push(...this.handleTree(response.data, "id"));
this.depts = response.data;
this.$refs.dept.setCheckedKeys(res.data.dataScopeDeptIds, false);
});
});
},
submitForm() {
if (this.form.id !== undefined) {
assignRoleDataScope({
roleId: this.form.id,
dataScope: this.form.dataScope,
dataScopeDeptIds:
this.form.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM
? []
: this.$refs.dept.getCheckedKeys(),
}).then((response) => {
this.$modal.msgSuccess("修改成功");
this.$emit("successSubmitd");
});
}
},
formClear() {
this.deptExpand = true;
this.deptNodeAll = false;
this.form = {
id: undefined,
name: undefined,
code: undefined,
deptIds: [],
dataScope: undefined,
deptCheckStrictly: false,
};
},
//
handleCheckedTreeConnect(value, type) {
if (type === "menu") {
this.form.menuCheckStrictly = value;
} else if (type === "dept") {
this.form.deptCheckStrictly = !value;
}
},
// /
handleCheckedTreeExpand(value, type) {
if (type === "menu") {
let treeList = this.menuOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
}
} else if (type === "dept") {
let treeList = this.deptOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
}
}
},
// /
handleCheckedTreeNodeAll(value, type) {
if (type === "menu") {
this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
} else if (type === "dept") {
// this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
this.$refs.dept.setCheckedNodes(value ? this.depts : []);
}
},
},
};
</script>

View File

@ -0,0 +1,146 @@
<template>
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.name" :disabled="true" />
</el-form-item>
<el-form-item label="角色标识">
<el-input v-model="form.code" :disabled="true" />
</el-form-item>
<el-form-item label="菜单权限">
<el-checkbox
v-model="menuExpand"
@change="handleCheckedTreeExpand($event, 'menu')"
>展开/折叠</el-checkbox
>
<el-checkbox
v-model="menuNodeAll"
@change="handleCheckedTreeNodeAll($event, 'menu')"
>全选/全不选</el-checkbox
>
<el-tree
class="tree-border"
:data="menuOptions"
show-checkbox
ref="menu"
node-key="id"
:check-strictly="form.menuCheckStrictly"
empty-text="加载中,请稍后"
:props="defaultProps"
></el-tree>
</el-form-item>
</el-form>
</template>
<script>
import { getRole } from "@/api/system/role";
import { SystemDataScopeEnum } from "@/utils/constants";
import { assignRoleMenu, listRoleMenus } from "@/api/system/permission";
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
import { listSimpleMenus } from "@/api/system/menu";
export default {
name: "MenuAuth",
data() {
return {
form: {
id: undefined,
name: undefined,
code: undefined,
menuIds: [],
menuCheckStrictly: true,
},
//
menuOptions: [],
menuExpand: false,
menuNodeAll: false,
SysDataScopeEnum: SystemDataScopeEnum,
//
dataScopeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_DATA_SCOPE),
defaultProps: {
label: "name",
children: "children",
},
};
},
methods: {
init(id) {
this.form.id = id;
getRole(id).then((res) => {
this.form.name = res.data.name;
this.form.code = res.data.code;
listSimpleMenus().then((response) => {
// menuOptions
this.menuOptions = [];
this.menuOptions.push(...this.handleTree(response.data, "id"));
//
listRoleMenus(id).then((response) => {
//
this.form.menuCheckStrictly = true;
//
this.$refs.menu.setCheckedKeys(response.data);
// 使
this.form.menuCheckStrictly = false;
});
});
});
},
submitForm() {
if (this.form.id !== undefined) {
assignRoleMenu({
roleId: this.form.id,
menuIds: [
...this.$refs.menu.getCheckedKeys(),
...this.$refs.menu.getHalfCheckedKeys(),
],
}).then((response) => {
this.$modal.msgSuccess("修改成功");
this.$emit("successSubmitm");
});
}
},
formClear() {
if (this.$refs.menu !== undefined) {
this.$refs.menu.setCheckedKeys([]);
}
this.menuExpand = false;
this.menuNodeAll = false;
this.form = {
id: undefined,
name: undefined,
code: undefined,
menuIds: [],
menuCheckStrictly: true,
};
},
//
handleCheckedTreeConnect(value, type) {
if (type === "menu") {
this.form.menuCheckStrictly = value;
} else if (type === "dept") {
this.form.deptCheckStrictly = !value;
}
},
// /
handleCheckedTreeExpand(value, type) {
if (type === "menu") {
let treeList = this.menuOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
}
} else if (type === "dept") {
let treeList = this.deptOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
}
}
},
// /
handleCheckedTreeNodeAll(value, type) {
if (type === "menu") {
this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
} else if (type === "dept") {
// this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
this.$refs.dept.setCheckedNodes(value ? this.depts : []);
}
},
},
};
</script>

View File

@ -0,0 +1,129 @@
<template>
<el-form ref="form" :rules="rules" label-width="100px" :model="form">
<el-row>
<el-col :span="24">
<el-form-item label="角色编码" prop="code">
<el-input v-model="form.code"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="角色顺序" prop="sort">
<el-input-number
v-model="form.sort"
controls-position="right"
:min="1"
:max="999999999"
style="width: 100%"
></el-input-number>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="status" v-if="isEdit">
<el-switch v-model="form.status"> </el-switch>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { addRole, getRole, updateRole } from "@/api/system/role";
export default {
name: "RoleAdd",
data() {
return {
form: {
id: "",
code: "",
name: "",
sort: 1,
status: 0,
remark: "",
},
isEdit: false, //
rules: {
code: [
{ required: true, message: "角色编码不能为空", trigger: "blur" },
],
name: [
{ required: true, message: "角色名称不能为空", trigger: "blur" },
],
sort: [{ required: true }],
},
};
},
methods: {
init(id) {
if (id) {
this.isEdit = true;
this.form.id = id;
getRole(id).then((res) => {
if (res.code === 0) {
this.form.id = res.data.id;
this.form.code = res.data.code;
this.form.name = res.data.name;
this.form.sort = res.data.sort;
this.form.remark = res.data.remark;
this.form.status = res.data.status ? false : true;
}
});
} else {
this.isEdit = false;
this.form.id = "";
}
},
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.isEdit) {
//
updateRole({
id: this.form.id,
code: this.form.code,
name: this.form.name,
sort: this.form.sort,
remark: this.form.remark,
status: this.form.status ? 0 : 1,
}).then((res) => {
if (res.code === 0) {
this.$modal.msgSuccess("操作成功");
this.$emit("successSubmit");
}
});
} else {
addRole({
code: this.form.code,
name: this.form.name,
sort: this.form.sort,
remark: this.form.remark,
status: 0,
}).then((res) => {
if (res.code === 0) {
this.$modal.msgSuccess("操作成功");
this.$emit("successSubmit");
}
});
}
} else {
return false;
}
});
},
formClear() {
this.$refs.form.resetFields();
this.isEdit = false;
},
},
};
</script>

View File

@ -1,250 +1,180 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- <doc-alert title="功能权限" url="https://doc.iocoder.cn/resource-permission" /> <!-- <doc-alert
title="功能权限"
url="https://doc.iocoder.cn/resource-permission"
/>
<doc-alert title="数据权限" url="https://doc.iocoder.cn/data-permission" /> --> <doc-alert title="数据权限" url="https://doc.iocoder.cn/data-permission" /> -->
<el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true"> <!-- 搜索工作栏 -->
<el-form-item label="角色名称" prop="name"> <search-bar
<el-input v-model="queryParams.name" placeholder="请输入角色名称" clearable size="small" style="width: 240px" :formConfigs="formConfig"
@keyup.enter.native="handleQuery"/> ref="searchBarForm"
</el-form-item> @headBtnClick="buttonClick" />
<el-form-item label="角色标识" prop="code"> <!-- 列表 -->
<el-input v-model="queryParams.code" placeholder="请输入角色标识" clearable size="small" style="width: 240px" <base-table
@keyup.enter.native="handleQuery"/> :page="queryParams.pageNo"
</el-form-item> :limit="queryParams.pageSize"
<el-form-item label="状态" prop="status"> :table-props="tableProps"
<el-select v-model="queryParams.status" placeholder="角色状态" clearable size="small" style="width: 240px"> :table-data="list"
<el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/> :max-height="tableH">
</el-select> <method-btn
</el-form-item> v-if="tableBtn.length"
<el-form-item label="创建时间" prop="createTime"> slot="handleBtn"
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" :width="230"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> label="操作"
</el-form-item> :method-list="tableBtn"
<el-form-item> @clickBtn="handleClick" />
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> </base-table>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> <pagination
</el-form-item> :page.sync="queryParams.pageNo"
</el-form> :limit.sync="queryParams.pageSize"
:total="total"
@pagination="getList" />
<el-row :gutter="10" class="mb8"> <!-- 新增&编辑 -->
<el-col :span="1.5"> <base-dialog
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" :dialogTitle="addOrEditTitle"
v-hasPermi="['system:role:create']">新增</el-button> :dialogVisible="centervisible"
</el-col> @cancel="handleCancel"
<el-col :span="1.5"> @confirm="handleConfirm"
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" :before-close="handleCancel"
v-hasPermi="['system:role:export']">导出</el-button> width="50%">
</el-col> <role-add ref="roleAdd" @successSubmit="successSubmit" />
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> </base-dialog>
</el-row> <!-- 菜单权限 -->
<base-dialog
<el-table v-loading="loading" :data="roleList"> dialogTitle="分配菜单权限"
<el-table-column label="角色编号" prop="id" width="120" /> :dialogVisible="menuVisible"
<el-table-column label="角色名称" prop="name" :show-overflow-tooltip="true" width="150" /> @cancel="handleCancelm"
<el-table-column label="角色标识" prop="code" :show-overflow-tooltip="true" width="150" /> @confirm="handleConfirmm"
<el-table-column label="角色类型" prop="type" width="80"> :before-close="handleCancelm"
<template v-slot="scope"> width="50%">
<dict-tag :type="DICT_TYPE.SYSTEM_ROLE_TYPE" :value="scope.row.type"/> <menu-auth ref="menuAuth" @successSubmitm="successSubmitm" />
</template> </base-dialog>
</el-table-column> <!-- 数据权限 -->
<el-table-column label="显示顺序" prop="sort" width="100" /> <base-dialog
<el-table-column label="状态" align="center" width="100"> dialogTitle="分配数据权限"
<template v-slot="scope"> :dialogVisible="dataVisible"
<el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)"/> @cancel="handleCanceld"
</template> @confirm="handleConfirmd"
</el-table-column> :before-close="handleCanceld"
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> width="50%">
<template v-slot="scope"> <data-auth ref="dataAuth" @successSubmitd="successSubmitd" />
<span>{{ parseTime(scope.row.createTime) }}</span> </base-dialog>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['system:role:update']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-circle-check" @click="handleMenu(scope.row)"
v-hasPermi="['system:permission:assign-role-menu']">菜单权限</el-button>
<el-button size="mini" type="text" icon="el-icon-circle-check" @click="handleDataScope(scope.row)"
v-hasPermi="['system:permission:assign-role-data-scope']">数据权限</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['system:role:delete']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
<!-- 添加或修改角色配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" placeholder="请输入角色名称" />
</el-form-item>
<el-form-item label="角色标识" prop="code">
<el-input v-model="form.code" placeholder="请输入角色标识" />
</el-form-item>
<el-form-item label="角色顺序" prop="sort">
<el-input-number v-model="form.sort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 分配角色的数据权限对话框 -->
<el-dialog title="分配数据权限" :visible.sync="openDataScope" width="500px" append-to-body>
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.name" :disabled="true" />
</el-form-item>
<el-form-item label="角色标识">
<el-input v-model="form.code" :disabled="true" />
</el-form-item>
<el-form-item label="权限范围">
<el-select v-model="form.dataScope">
<el-option
v-for="item in dataScopeDictDatas"
:key="parseInt(item.value)"
:label="item.label"
:value="parseInt(item.value)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据权限" v-show="form.dataScope === SysDataScopeEnum.DEPT_CUSTOM">
<el-checkbox :checked="!form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动(选中父节点自动选择子节点)</el-checkbox>
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
<el-tree
class="tree-border"
:data="deptOptions"
show-checkbox
default-expand-all
ref="dept"
node-key="id"
:check-strictly="form.deptCheckStrictly"
empty-text="加载中,请稍后"
:props="defaultProps"
></el-tree>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitDataScope"> </el-button>
<el-button @click="cancelDataScope"> </el-button>
</div>
</el-dialog>
<!-- 分配角色的菜单权限对话框 -->
<el-dialog :title="title" :visible.sync="openMenu" width="500px" append-to-body>
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.name" :disabled="true" />
</el-form-item>
<el-form-item label="角色标识">
<el-input v-model="form.code" :disabled="true" />
</el-form-item>
<el-form-item label="菜单权限">
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
<el-tree class="tree-border" :data="menuOptions" show-checkbox ref="menu" node-key="id"
:check-strictly="form.menuCheckStrictly" empty-text="加载中,请稍后" :props="defaultProps"></el-tree>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitMenu"> </el-button>
<el-button @click="cancelMenu"> </el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { import { delRole, listRole } from '@/api/system/role';
addRole, import tableHeightMixin from '@/mixins/tableHeightMixin';
changeRoleStatus, import RoleAdd from './components/roleAdd';
delRole, import MenuAuth from './components/menuAuth';
exportRole, import DataAuth from './components/dataAuth';
getRole, import statusBtn from './../components/statusBtn.vue';
listRole, const tableProps = [
updateRole {
} from "@/api/system/role"; prop: 'code',
import {listSimpleMenus} from "@/api/system/menu"; label: '角色编码',
import {assignRoleMenu, listRoleMenus, assignRoleDataScope} from "@/api/system/permission"; minWidth: 140,
import {listSimpleDepts} from "@/api/system/dept"; showOverflowtooltip: true,
import {CommonStatusEnum, SystemDataScopeEnum} from "@/utils/constants"; },
import {DICT_TYPE, getDictDatas} from "@/utils/dict"; {
prop: 'name',
label: '角色名称',
minWidth: 140,
showOverflowtooltip: true,
},
{
prop: 'sort',
label: '角色顺序',
minWidth: 90,
showOverflowtooltip: true,
},
{
prop: 'status',
label: '状态',
minWidth: 100,
subcomponent: statusBtn,
},
{
prop: 'remark',
label: '角色描述',
minWidth: 140,
showOverflowtooltip: true,
},
];
export default { export default {
name: "SystemRole", name: 'SystemRole',
mixins: [tableHeightMixin],
components: { RoleAdd, MenuAuth, DataAuth },
data() { data() {
return { return {
// formConfig: [
loading: true, {
// type: 'input',
exportLoading: false, label: '角色名称',
// placeholder: '角色名称',
showSearch: true, param: 'name',
// },
total: 0, {
// type: 'button',
roleList: [], btnName: '查询',
// name: 'search',
title: "", color: 'primary',
// },
open: false, {
// type: this.$auth.hasPermi('system:role:create') ? 'separate' : '',
openDataScope: false, },
// {
openMenu: false, type: this.$auth.hasPermi('system:role:create') ? 'button' : '',
menuExpand: false, btnName: '新增',
menuNodeAll: false, name: 'add',
deptExpand: true, color: 'success',
deptNodeAll: false, plain: true,
// },
menuOptions: [], ],
//
deptOptions: [], //
depts: [], //
//
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 20,
name: undefined, name: '',
code: undefined,
status: undefined,
createTime: []
}, },
// tableProps,
form: {}, list: [],
defaultProps: { tableBtn: [
label: "name", this.$auth.hasPermi('system:permission:assign-role-menu')
children: "children" ? {
}, type: 'menuAuth',
// btnName: '菜单权限',
rules: { }
name: [ : undefined,
{ required: true, message: "角色名称不能为空", trigger: "blur" } this.$auth.hasPermi('system:permission:assign-role-data-scope')
], ? {
code: [ type: 'dataAuth',
{ required: true, message: "角色标识不能为空", trigger: "blur" } btnName: '数据权限',
], // showTip: "",
sort: [ }
{ required: true, message: "角色顺序不能为空", trigger: "blur" } : undefined,
] this.$auth.hasPermi('system:role:update')
}, ? {
type: 'edit',
// btnName: '编辑',
SysCommonStatusEnum: CommonStatusEnum, }
SysDataScopeEnum: SystemDataScopeEnum, : undefined,
// this.$auth.hasPermi('system:role:delete')
roleTypeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_ROLE_TYPE), ? {
statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS), type: 'delete',
dataScopeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_DATA_SCOPE) btnName: '删除',
}
: undefined,
].filter((v) => v),
addOrEditTitle: '',
centervisible: false,
//
menuVisible: false,
//
dataVisible: false,
//
total: 0,
}; };
}, },
created() { created() {
@ -253,243 +183,110 @@ export default {
methods: { methods: {
/** 查询角色列表 */ /** 查询角色列表 */
getList() { getList() {
this.loading = true; listRole(this.queryParams).then((response) => {
listRole(this.queryParams).then( this.list = response.data.list;
response => {
this.roleList = response.data.list;
this.total = response.data.total; this.total = response.data.total;
this.loading = false;
}
);
},
//
handleStatusChange(row) {
// row
let text = row.status === CommonStatusEnum.ENABLE ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""' + row.name + '"角色吗?').then(function() {
return changeRoleStatus(row.id, row.status);
}).then(() => {
this.$modal.msgSuccess(text + "成功");
}).catch(function() {
// row.status
row.status = row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE
: CommonStatusEnum.ENABLE;
}); });
}, },
// buttonClick(val) {
cancel() { console.log(val);
this.open = false; if (val.btnName === 'search') {
this.reset();
},
//
cancelDataScope() {
this.openDataScope = false;
this.reset();
},
//
cancelMenu() {
this.openMenu = false;
this.reset();
},
//
reset() {
if (this.$refs.menu !== undefined) {
this.$refs.menu.setCheckedKeys([]);
}
this.menuExpand = false;
this.menuNodeAll = false;
this.deptExpand = true;
this.deptNodeAll = false;
this.form = {
id: undefined,
name: undefined,
code: undefined,
sort: 0,
deptIds: [],
menuIds: [],
dataScope: undefined,
deptCheckStrictly: false,
menuCheckStrictly: true,
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1; this.queryParams.pageNo = 1;
this.queryParams.name = val.name;
this.getList(); this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// /
handleCheckedTreeExpand(value, type) {
if (type === 'menu') {
let treeList = this.menuOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
}
} else if (type === 'dept') {
let treeList = this.deptOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
}
}
},
// /
handleCheckedTreeNodeAll(value, type) {
if (type === 'menu') {
this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
} else if (type === 'dept') {
// this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
this.$refs.dept.setCheckedNodes(value ? this.depts: []);
}
},
//
handleCheckedTreeConnect(value, type) {
if (type === 'menu') {
this.form.menuCheckStrictly = value;
} else if (type === 'dept') {
this.form.deptCheckStrictly = !value;
}
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加角色";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id
getRole(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改角色";
});
},
/** 分配菜单权限操作 */
handleMenu(row) {
this.reset();
const id = row.id
// form name code
this.form.id = id;
this.form.name = row.name;
this.form.code = row.code;
//
this.openMenu = true;
//
listSimpleMenus().then(response => {
// menuOptions
this.menuOptions = [];
this.menuOptions.push(...this.handleTree(response.data, "id"));
//
listRoleMenus(id).then(response => {
//
this.form.menuCheckStrictly = true
//
this.$refs.menu.setCheckedKeys(response.data);
// 使
this.form.menuCheckStrictly = false
})
});
},
/** 分配数据权限操作 */
handleDataScope(row) {
this.reset();
// form name code
this.form.id = row.id;
this.form.name = row.name;
this.form.code = row.code;
//
this.openDataScope = true;
//
listSimpleDepts().then(response => {
// deptOptions
this.deptOptions = [];
this.deptOptions.push(...this.handleTree(response.data, "id"));
this.depts = response.data;
// this.deptIds = response.data.map(x => x.id);
//
getRole(row.id).then(response => {
this.form.dataScope = response.data.dataScope;
this.$refs.dept.setCheckedKeys(response.data.dataScopeDeptIds, false);
});
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateRole(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else { } else {
addRole(this.form).then(response => { this.addOrEditTitle = '新增';
this.$modal.msgSuccess("新增成功"); this.centervisible = true;
this.open = false; this.$nextTick(() => {
this.getList(); this.$refs.roleAdd.init();
});
}
}
});
},
/** 提交按钮(数据权限) */
submitDataScope: function() {
if (this.form.id !== undefined) {
assignRoleDataScope({
roleId: this.form.id,
dataScope: this.form.dataScope,
dataScopeDeptIds: this.form.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM ? [] :
this.$refs.dept.getCheckedKeys()
}).then(response => {
this.$modal.msgSuccess("修改成功");
this.openDataScope = false;
this.getList();
}); });
} }
}, },
/** 提交按钮(菜单权限) */ handleClick(val) {
submitMenu: function() { switch (val.type) {
if (this.form.id !== undefined) { case 'edit':
assignRoleMenu({ this.addOrEditTitle = '编辑';
roleId: this.form.id, this.centervisible = true;
menuIds: [...this.$refs.menu.getCheckedKeys(), ...this.$refs.menu.getHalfCheckedKeys()] this.$nextTick(() => {
}).then(response => { this.$refs.roleAdd.init(val.data.id);
this.$modal.msgSuccess("修改成功"); });
this.openMenu = false; break;
this.getList(); case 'delete':
this.handleDelete(val.data);
break;
case 'menuAuth':
this.menuVisible = true;
this.$nextTick(() => {
this.$refs.menuAuth.init(val.data.id);
});
break;
default:
this.dataVisible = true;
this.$nextTick(() => {
this.$refs.dataAuth.init(val.data.id);
}); });
} }
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; this.$modal
this.$modal.confirm('是否确认删除角色编号为"' + ids + '"的数据项?').then(function() { .delConfirm(row.name)
return delRole(ids); .then(function () {
}).then(() => { return delRole(row.id);
})
.then(() => {
this.queryParams.pageNo = 1;
this.getList(); this.getList();
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess('删除成功');
}).catch(() => {}); })
.catch(() => {});
},
//
handleCancel() {
this.$refs.roleAdd.formClear();
this.centervisible = false;
this.addOrEditTitle = '';
},
handleConfirm() {
this.$refs.roleAdd.submitForm();
},
successSubmit() {
this.handleCancel();
this.getList();
},
//
handleCancelm() {
this.$refs.menuAuth.formClear();
this.menuVisible = false;
},
handleConfirmm() {
this.$refs.menuAuth.submitForm();
},
successSubmitm() {
this.handleCancelm();
this.getList();
},
//
handleCanceld() {
this.$refs.dataAuth.formClear();
this.dataVisible = false;
},
handleConfirmd() {
this.$refs.dataAuth.submitForm();
},
successSubmitd() {
this.handleCanceld();
this.getList();
},
}, },
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有角色数据项?').then(function() {
this.exportLoading = true;
return exportRole(queryParams);
}).then(response => {
this.$download.excel(response, '角色数据.xls');
this.exportLoading = false;
}).catch(() => {});
}
}
}; };
</script> </script>
<style lang="scss" scoped>
.app-container {
width: 100%;
height: calc(100vh - 164px);
background-color: #fff;
border-radius: 8px;
padding: 8px;
}
</style>

View File

@ -1,8 +1,17 @@
<template> <template>
<div style="display: flex; gap: 16px; flex: 1; background: #eff1f6"> <div class="user-container">
<div <!-- <doc-alert title="用户体系" url="https://doc.iocoder.cn/user-center/" />
class="app-container" <doc-alert title="三方登陆" url="https://doc.iocoder.cn/social-user/" />
style="background: white; width: 280px; border-radius: 8px"> <doc-alert
title="Excel 导入导出"
url="https://doc.iocoder.cn/excel-import-and-export/"
/> -->
<!-- 搜索工作栏 -->
<el-row :gutter="8" class="user-box">
<!--部门数据-->
<el-col :span="4" :xs="24">
<div class="user-box-left">
<div class="head-container"> <div class="head-container">
<el-input <el-input
v-model="deptName" v-model="deptName"
@ -24,240 +33,47 @@
@node-click="handleNodeClick" /> @node-click="handleNodeClick" />
</div> </div>
</div> </div>
<div
class="app-container"
style="background: #fff; border-radius: 8px; width: 1px; flex: 1">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px">
<el-form-item label="用户名称" prop="username">
<el-input
v-model="queryParams.username"
placeholder="请输入用户名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="手机号码" prop="mobile">
<el-input
v-model="queryParams.mobile"
placeholder="请输入手机号码"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="用户状态"
clearable
style="width: 240px">
<el-option
v-for="dict in statusDictDatas"
:key="parseInt(dict.value)"
:label="dict.label"
:value="parseInt(dict.value)" />
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">
搜索
</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:user:create']">
新增
</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <!--用户数据-->
<el-button <el-col :span="20" :xs="24">
type="info" <div class="user-box-right">
icon="el-icon-upload2" <search-bar
size="mini" :formConfigs="formConfig"
@click="handleImport" ref="userSearchBarForm"
v-hasPermi="['system:user:import']"> @headBtnClick="buttonClick" />
导入 <!-- 列表 -->
</el-button> <base-table
</el-col> :page="queryParams.pageNo"
<el-col :span="1.5"> :limit="queryParams.pageSize"
<el-button :table-props="tableProps"
type="warning" :table-data="userList"
icon="el-icon-download" :max-height="tableH"
size="mini" @emitFun="handleStatusChange">
@click="handleExport" <method-btn
:loading="exportLoading" v-if="tableBtn.length"
v-hasPermi="['system:user:export']"> slot="handleBtn"
导出 :width="220"
</el-button>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
:columns="columns"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="userList">
<el-table-column
label="用户编号"
align="center"
key="id"
prop="id"
v-if="columns[0].visible" />
<el-table-column
label="用户名称"
align="center"
key="username"
prop="username"
v-if="columns[1].visible"
:show-overflow-tooltip="true" />
<el-table-column
label="用户昵称"
align="center"
key="nickname"
prop="nickname"
v-if="columns[2].visible"
:show-overflow-tooltip="true" />
<el-table-column
label="部门"
align="center"
key="deptName"
prop="dept.name"
v-if="columns[3].visible"
:show-overflow-tooltip="true" />
<el-table-column
label="手机号码"
align="center"
key="mobile"
prop="mobile"
v-if="columns[4].visible"
width="120" />
<el-table-column
label="状态"
key="status"
v-if="columns[5].visible"
align="center">
<template v-slot="scope">
<el-switch
v-model="scope.row.status"
:active-value="0"
:inactive-value="1"
@change="handleStatusChange(scope.row)" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
v-if="columns[6].visible"
width="160">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作" label="操作"
align="center" :method-list="tableBtn"
width="160" @clickBtn="handleClick" />
class-name="small-padding fixed-width"> </base-table>
<template v-slot="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:user:update']">
修改
</el-button>
<el-dropdown
@command="
(command) => handleCommand(command, scope.$index, scope.row)
"
v-hasPermi="[
'system:user:delete',
'system:user:update-password',
'system:permission:assign-user-role',
]">
<el-button size="mini" type="text" icon="el-icon-d-arrow-right">
更多
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
command="handleDelete"
v-if="scope.row.id !== 1"
size="mini"
type="text"
icon="el-icon-delete"
v-hasPermi="['system:user:delete']">
删除
</el-dropdown-item>
<el-dropdown-item
command="handleResetPwd"
size="mini"
type="text"
icon="el-icon-key"
v-hasPermi="['system:user:update-password']">
重置密码
</el-dropdown-item>
<el-dropdown-item
command="handleRole"
size="mini"
type="text"
icon="el-icon-circle-check"
v-hasPermi="['system:permission:assign-user-role']">
分配角色
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination <pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo" :page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.pageSize"
:total="total"
@pagination="getList" /> @pagination="getList" />
</div>
</el-col>
</el-row>
<!-- 添加或修改参数配置对话框 --> <!-- 添加或修改参数配置对话框 -->
<el-dialog <base-dialog :dialogTitle="title" :dialogVisible="open" width="50%">
:title="title" <el-form ref="form" :model="form" :rules="rules" label-width="100px">
:visible.sync="open"
width="600px"
append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户昵称" prop="nickname"> <el-form-item label="用户昵称" prop="nickname">
<el-input <el-input v-model="form.nickname" placeholder="请输入用户昵称" />
v-model="form.nickname"
placeholder="请输入用户昵称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -296,9 +112,7 @@
v-if="form.id === undefined" v-if="form.id === undefined"
label="用户名称" label="用户名称"
prop="username"> prop="username">
<el-input <el-input v-model="form.username" placeholder="请输入用户名称" />
v-model="form.username"
placeholder="请输入用户名称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -317,7 +131,10 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户性别"> <el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择"> <el-select
v-model="form.sex"
placeholder="请选择"
style="width: 100%">
<el-option <el-option
v-for="dict in sexDictDatas" v-for="dict in sexDictDatas"
:key="parseInt(dict.value)" :key="parseInt(dict.value)"
@ -328,7 +145,11 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="岗位"> <el-form-item label="岗位">
<el-select v-model="form.postIds" multiple placeholder="请选择"> <el-select
v-model="form.postIds"
multiple
placeholder="请选择"
style="width: 100%">
<el-option <el-option
v-for="item in postOptions" v-for="item in postOptions"
:key="item.id" :key="item.id"
@ -350,17 +171,16 @@
</el-row> </el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</div> </div>
</el-dialog> </base-dialog>
<!-- 用户导入对话框 --> <!-- 用户导入对话框 -->
<el-dialog <base-dialog
:title="upload.title" :dialogTitle="upload.title"
:visible.sync="upload.open" :dialogVisible="upload.open"
width="400px" width="400px">
append-to-body>
<el-upload <el-upload
ref="upload" ref="upload"
:limit="1" :limit="1"
@ -388,7 +208,7 @@
:underline="false" :underline="false"
style="font-size: 12px; vertical-align: baseline" style="font-size: 12px; vertical-align: baseline"
@click="importTemplate"> @click="importTemplate">
下载模板 导出模板
</el-link> </el-link>
</div> </div>
</el-upload> </el-upload>
@ -396,14 +216,10 @@
<el-button type="primary" @click="submitFileForm"> </el-button> <el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button> <el-button @click="upload.open = false"> </el-button>
</div> </div>
</el-dialog> </base-dialog>
<!-- 分配角色 --> <!-- 分配角色 -->
<el-dialog <base-dialog dialogTitle="分配角色" :dialogVisible="openRole" width="500px">
title="分配角色"
:visible.sync="openRole"
width="500px"
append-to-body>
<el-form :model="form" label-width="80px"> <el-form :model="form" label-width="80px">
<el-form-item label="用户名称"> <el-form-item label="用户名称">
<el-input v-model="form.username" :disabled="true" /> <el-input v-model="form.username" :disabled="true" />
@ -412,7 +228,11 @@
<el-input v-model="form.nickname" :disabled="true" /> <el-input v-model="form.nickname" :disabled="true" />
</el-form-item> </el-form-item>
<el-form-item label="角色"> <el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择"> <el-select
v-model="form.roleIds"
multiple
placeholder="请选择"
style="width: 100%">
<el-option <el-option
v-for="item in roleOptions" v-for="item in roleOptions"
:key="parseInt(item.id)" :key="parseInt(item.id)"
@ -425,8 +245,7 @@
<el-button type="primary" @click="submitRole"> </el-button> <el-button type="primary" @click="submitRole"> </el-button>
<el-button @click="cancelRole"> </el-button> <el-button @click="cancelRole"> </el-button>
</div> </div>
</el-dialog> </base-dialog>
</div>
</div> </div>
</template> </template>
@ -453,12 +272,168 @@ import { DICT_TYPE, getDictDatas } from '@/utils/dict';
import { assignUserRole, listUserRoles } from '@/api/system/permission'; import { assignUserRole, listUserRoles } from '@/api/system/permission';
import { listSimpleRoles } from '@/api/system/role'; import { listSimpleRoles } from '@/api/system/role';
import { getBaseHeader } from '@/utils/request'; import { getBaseHeader } from '@/utils/request';
import tableHeightMixin from '@/mixins/tableHeightMixin';
import { parseTime } from '@/utils/ruoyi';
import statusBtn5 from './../components/statusBtn5.vue';
const tableProps = [
{
prop: 'id',
label: '用户编号',
showOverflowtooltip: true,
},
{
prop: 'username',
label: '用户名称',
minWidth: 120,
showOverflowtooltip: true,
},
{
prop: 'nickname',
label: '用户昵称',
minWidth: 120,
showOverflowtooltip: true,
},
{
prop: 'dept',
label: '部门',
minWidth: 120,
filter: (item) => item.name || '',
showOverflowtooltip: true,
},
{
prop: 'mobile',
label: '手机号码',
minWidth: 150,
showOverflowtooltip: true,
},
{
prop: 'status',
label: '状态',
minWidth: 80,
// filter: publicFormatter(DICT_TYPE.SYSTEM_OPERATE_TYPE),
subcomponent: statusBtn5,
},
{
prop: 'createTime',
label: '创建时间',
filter: parseTime,
minWidth: 150,
showOverflowtooltip: true,
},
];
export default { export default {
name: 'SystemUser', name: 'SystemUser',
mixins: [tableHeightMixin],
components: { Treeselect }, components: { Treeselect },
data() { data() {
return { return {
formConfig: [
{
type: 'input',
label: '用户名称',
placeholder: '用户名称',
param: 'username',
width: 150,
},
{
type: 'input',
label: '手机号码',
placeholder: '手机号码',
param: 'mobile',
width: 150,
},
{
type: 'select',
label: '状态',
selectOptions: this.getDictDatas(this.DICT_TYPE.COMMON_STATUS),
labelField: 'label',
valueField: 'value',
param: 'status',
width: 100,
},
{
type: 'datePicker',
label: '创建时间',
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
param: 'createTime',
defaultSelect: [],
defaultTime: ['00:00:00', '23:59:59'],
width: 250,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'button',
btnName: '重置',
name: 'cancel',
},
{
type: this.$auth.hasPermiOr([
'system:user:create',
'system:user:import',
'system:user:export',
])
? 'separate'
: '',
},
{
type: this.$auth.hasPermi('system:user:import') ? 'button' : '',
btnName: '导入',
name: 'import',
color: 'primary',
plain: true,
},
{
type: this.$auth.hasPermi('system:user:export') ? 'button' : '',
btnName: '导出',
name: 'export',
color: 'primary',
plain: true,
},
{
type: this.$auth.hasPermi('system:user:create') ? 'button' : '',
btnName: '新增',
name: 'addNew',
color: 'success',
plain: true,
},
],
tableBtn: [
this.$auth.hasPermi('system:user:update-password')
? {
type: 'reset',
btnName: '重置密码',
}
: undefined,
this.$auth.hasPermi('system:permission:assign-user-role')
? {
type: 'role',
btnName: '分配角色',
}
: undefined,
this.$auth.hasPermi('system:user:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('system:user:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps,
// //
loading: true, loading: true,
// //
@ -468,7 +443,7 @@ export default {
// //
total: 0, total: 0,
// //
userList: null, userList: [],
// //
title: '', title: '',
// //
@ -509,23 +484,13 @@ export default {
// //
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 20,
username: undefined, username: undefined,
mobile: undefined, mobile: undefined,
status: undefined, status: undefined,
deptId: undefined, deptId: undefined,
createTime: [], createTime: [],
}, },
//
columns: [
{ key: 0, label: `用户编号`, visible: true },
{ key: 1, label: `用户名称`, visible: true },
{ key: 2, label: `用户昵称`, visible: true },
{ key: 3, label: `部门`, visible: true },
{ key: 4, label: `手机号码`, visible: true },
{ key: 5, label: `状态`, visible: true },
{ key: 6, label: `创建时间`, visible: true },
],
// //
rules: { rules: {
username: [ username: [
@ -577,23 +542,44 @@ export default {
// }); // });
}, },
methods: { methods: {
// handleClick(val) {
handleCommand(command, index, row) { switch (val.type) {
switch (command) { case 'edit':
case 'handleUpdate': this.handleUpdate(val.data);
this.handleUpdate(row); //
break; break;
case 'handleDelete': case 'delete':
this.handleDelete(row); // this.handleDelete(val.data.id, val.data.username);
break; break;
case 'handleResetPwd': case 'reset':
this.handleResetPwd(row); this.handleResetPwd(val.data);
break;
case 'handleRole':
this.handleRole(row);
break; break;
default: default:
this.handleRole(val.data);
}
},
buttonClick(val) {
console.log(val);
switch (val.btnName) {
case 'search':
this.handleQuery(val);
break; break;
case 'cancel':
this.$refs['userSearchBarForm'].resetForm();
this.queryParams.pageNo = 1;
this.queryParams.username = '';
this.queryParams.mobile = '';
this.queryParams.status = '';
this.queryParams.createTime = [];
this.getList();
break;
case 'addNew':
this.handleAdd();
break;
case 'import':
this.handleImport();
break;
default:
this.handleExport();
} }
}, },
/** 查询用户列表 */ /** 查询用户列表 */
@ -630,20 +616,8 @@ export default {
}, },
// //
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用'; changeUserStatus(row.id, row.status).then((res) => {
this.$modal this.$modal.msgSuccess('操作成功');
.confirm('确认要"' + text + '""' + row.username + '"用户吗?')
.then(function () {
return changeUserStatus(row.id, row.status);
})
.then(() => {
this.$modal.msgSuccess(text + '成功');
})
.catch(function () {
row.status =
row.status === CommonStatusEnum.ENABLE
? CommonStatusEnum.DISABLE
: CommonStatusEnum.ENABLE;
}); });
}, },
// //
@ -675,15 +649,14 @@ export default {
this.resetForm('form'); this.resetForm('form');
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery(val) {
this.queryParams.pageNo = 1; this.queryParams.pageNo = 1;
this.queryParams.username = val.username;
this.queryParams.mobile = val.mobile;
this.queryParams.status = val.status;
this.queryParams.createTime = val.createTime;
this.getList(); this.getList();
}, },
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
@ -703,15 +676,12 @@ export default {
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = '修改用户'; this.title = '修改用户';
this.form.password = '';
}); });
}, },
/** 重置密码按钮操作 */ /** 重置密码按钮操作 */
handleResetPwd(row) { handleResetPwd(row) {
this.$prompt('请输入"' + row.username + '"的新密码', '提示', { this.$modal
confirmButtonText: '确定', .prompt('请输入 【' + row.username + '】 的新密码')
cancelButtonText: '取消',
})
.then(({ value }) => { .then(({ value }) => {
resetUserPwd(row.id, value).then((response) => { resetUserPwd(row.id, value).then((response) => {
this.$modal.msgSuccess('修改成功,新密码是:' + value); this.$modal.msgSuccess('修改成功,新密码是:' + value);
@ -775,12 +745,11 @@ export default {
} }
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(id, detContent) {
const ids = row.id || this.ids;
this.$modal this.$modal
.confirm('是否确认删除用户编号为"' + ids + '"的数据项?') .delConfirm(detContent)
.then(function () { .then(() => {
return delUser(ids); return delUser(id);
}) })
.then(() => { .then(() => {
this.getList(); this.getList();
@ -811,7 +780,7 @@ export default {
this.upload.title = '用户导入'; this.upload.title = '用户导入';
this.upload.open = true; this.upload.open = true;
}, },
/** 下载模板操作 */ /** 导出模板操作 */
importTemplate() { importTemplate() {
importTemplate().then((response) => { importTemplate().then((response) => {
this.$download.excel(response, '用户导入模板.xls'); this.$download.excel(response, '用户导入模板.xls');
@ -867,3 +836,20 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss" scoped>
.user-container {
width: 100%;
height: calc(100vh - 164px);
background-color: #f2f4f9;
.user-box {
.user-box-left,
.user-box-right {
background-color: #fff;
padding: 8px;
border-radius: 8px;
height: calc(100vh - 164px);
}
}
}
</style>

View File

@ -7,9 +7,9 @@
<span>个人信息</span> <span>个人信息</span>
</div> </div>
<div> <div>
<!-- <div class="text-center"> <div class="text-center">
<userAvatar :user="user" /> <userAvatar :user="user" />
</div> --> </div>
<ul class="list-group list-group-striped"> <ul class="list-group list-group-striped">
<li class="list-group-item"> <li class="list-group-item">
<svg-icon icon-class="user" />用户名称 <svg-icon icon-class="user" />用户名称
@ -66,7 +66,7 @@
</template> </template>
<script> <script>
// import userAvatar from "./userAvatar"; import userAvatar from "./userAvatar";
import userInfo from "./userInfo"; import userInfo from "./userInfo";
import resetPwd from "./resetPwd"; import resetPwd from "./resetPwd";
import userSocial from "./userSocial"; import userSocial from "./userSocial";
@ -74,7 +74,7 @@ import { getUserProfile } from "@/api/system/user";
export default { export default {
name: "Profile", name: "Profile",
components: { /** userAvatar , **/ userInfo, resetPwd, userSocial }, components: { userAvatar, userInfo, resetPwd, userSocial },
data() { data() {
return { return {
user: {}, user: {},

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2022-08-24 11:19:43 * @Date: 2022-08-24 11:19:43
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2023-11-21 10:37:05 * @LastEditTime: 2024-08-09 15:51:09
* @Description: * @Description:
*/ */
export default { export default {
@ -17,7 +17,7 @@ export default {
}, },
tableData: [], tableData: [],
listQuery: { listQuery: {
pageSize: 10, pageSize: 20,
pageNo: 1, pageNo: 1,
total: 1, total: 1,
}, },
@ -41,6 +41,8 @@ export default {
if(response.hasOwnProperty('data')){ if(response.hasOwnProperty('data')){
this.tableData = response.data.list; this.tableData = response.data.list;
this.listQuery.total = response.data.total; this.listQuery.total = response.data.total;
}else{
this.tableData = []
} }
this.dataListLoading = false; this.dataListLoading = false;
}); });
@ -104,11 +106,8 @@ export default {
}, },
// 删除 // 删除
deleteHandle(id, name, index) { deleteHandle(id, name, index) {
this.$confirm(`是否确认删除${name ? '名称为"' + name + '"' : '序号为"' + index + '"'}的数据项?`, "系统提示", { this.$modal
confirmButtonText: "确定", .delConfirm(name ? '名称: ' + name : '序号: ' + index)
cancelButtonText: "取消",
type: "warning",
})
.then(() => { .then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => { this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({ this.$message({

View File

@ -2,7 +2,7 @@
/* /*
* @Date: 2020-12-29 16:49:28 * @Date: 2020-12-29 16:49:28
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2023-10-24 16:30:25 * @LastEditTime: 2024-08-07 15:57:27
* @FilePath: \basic-admin\src\filters\basicData\index.js * @FilePath: \basic-admin\src\filters\basicData\index.js
* @Description: * @Description:
*/ */
@ -17,11 +17,6 @@ const table = {
1: '启用', 1: '启用',
0: '停用', 0: '停用',
}, },
wareType: {
1: '缓存',
2: '活动',
3: '其它',
},
} }
// 日期格式化 // 日期格式化

View File

@ -0,0 +1,73 @@
<!--
* @Author: zwq
* @Date: 2024-07-01 14:54:06
* @LastEditors: zwq
* @LastEditTime: 2024-07-30 14:49:14
* @Description:
-->
<template>
<div class="warehouse-base">
<div class="operationArea">
<el-tabs v-model="pane" @tab-click="setPane" stretch>
<el-tab-pane label="仓库设置" name="warehouseSetup">
<warehouseSetup
ref="warehouseSetup"
v-if="pane === 'warehouseSetup'"></warehouseSetup>
</el-tab-pane>
<el-tab-pane label="库区设置" name="areaSetup">
<areaSetup
ref="areaSetup"
v-if="pane === 'areaSetup'"></areaSetup>
</el-tab-pane>
<el-tab-pane label="库位设置" name="locationSetup">
<locationSetup
ref="locationSetup"
v-if="pane === 'locationSetup'"></locationSetup>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import areaSetup from './warehouse-area-setup';
import locationSetup from './warehouse-location-setup';
import warehouseSetup from './warehouse-setup';
export default {
name: 'warehouseBase',
components: {
warehouseSetup,
areaSetup,
locationSetup,
},
data() {
return {
pane: 'warehouseSetup',
};
},
created() {
this.$nextTick(() => {
this.$refs.warehouseSetup.getDataList();
});
},
methods: {
setPane() {
this.$nextTick(() => {
this.$refs[this.pane].getDataList();
});
},
},
};
</script>
<style lang="scss">
.warehouse-base {
background-color: #f2f4f9;
.operationArea {
background-color: #fff;
border-radius: 8px;
}
.el-tabs__header {
padding: 14px 50% 0 10px;
}
}
</style>

View File

@ -0,0 +1,124 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 13:52:10
* @LastEditors: zwq
* @LastEditTime: 2024-07-30 15:06:35
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
v-if="visible"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="仓库名称" prop="warehouseId">
<el-select
v-model="dataForm.warehouseId"
filterable
clearable
:style="{ width: '100%' }"
placeholder="请选择仓库名称">
<el-option
v-for="item in warehouseArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="库区名称" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入库区名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="库区类型" prop="areaType">
<el-input
v-model="dataForm.areaType"
clearable
placeholder="请输入库区类型" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="enabled" label="是否启用">
<el-select
v-model="dataForm.enabled"
filterable
:style="{ width: '100%' }"
placeholder="请选择是否启用">
<el-option
v-for="item in isorno"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../../mixins/basic-add';
import {
createWarehouseArea,
updateWarehouseArea,
getWarehouseArea,
} from "@/api/warehouse/warehouse-area-setup";
import {
getWarehouseList
} from "@/api/warehouse/warehouse-setup";
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: createWarehouseArea,
updateURL: updateWarehouseArea,
infoURL: getWarehouseArea,
},
dataForm: {
id: undefined,
name: '',
warehouseId: '',
enabled: 1,
areaType: ''
},
dataRule: {
warehouseId: [
{ required: true, message: '仓库名称不能为空', trigger: 'change' },
],
name: [
{ required: true, message: '库区名称不能为空', trigger: 'blur' },
],
},
warehouseArr: [],
isorno: [
{
id: 0,
name: '停用',
},
{
id: 1,
name: '启用',
},
],
};
},
created() {
getWarehouseList().then((response) => {
this.warehouseArr = response.data;
});
},
methods: {},
};
</script>

View File

@ -0,0 +1,185 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<!-- 列表 -->
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:max-height="tableH"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="40%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../../mixins/basic-page';
import codeFilter from '../../mixins/code-filter';
import {
deleteWarehouseArea,
getWarehouseAreaPage,
getWarehouseAreaList
} from "@/api/warehouse/warehouse-area-setup";
import {
getWarehouseList
} from "@/api/warehouse/warehouse-setup";
import tableHeightMixin from '@/mixins/tableHeightMixin';
const tableProps = [
{
prop: 'warehouseName',
label: '仓库名称',
},
{
prop: 'name',
label: '库区名称',
},
{
prop: 'areaType',
label: '库区类型',
},
{
prop: 'enabled',
label: '是否启用',
filter: codeFilter('deactivate'),
},
];
export default {
mixins: [basicPage,tableHeightMixin],
data() {
return {
urlOptions: {
getDataListURL: getWarehouseAreaPage,
deleteURL: deleteWarehouseArea,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`warehouse:warehouse-area-setup:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`warehouse:warehouse-area-setup:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'select',
label: '仓库',
selectOptions: [],
param: 'warehouseId',
defaultSelect: '',
filterable: true,
},
{
type: 'select',
label: '库区',
selectOptions: [],
param: 'areaId',
defaultSelect: '',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('warehouse:warehouse-area-setup:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
};
},
components: {
AddOrUpdate,
},
created() {
getWarehouseList().then((response) => {
this.formConfig[0].selectOptions = response.data;
});
getWarehouseAreaList().then((response) => {
this.formConfig[1].selectOptions = response.data;
});
},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.warehouseId = val.warehouseId;
this.listQuery.areaId = val.areaId;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 20,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -0,0 +1,223 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 13:52:10
* @LastEditors: zwq
* @LastEditTime: 2024-08-07 15:53:15
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
v-if="visible"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="仓库名称" prop="warehouseId">
<el-select
v-model="dataForm.warehouseId"
filterable
clearable
:style="{ width: '100%' }"
placeholder="请选择仓库名称">
<el-option
v-for="item in warehouseArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库区名称" prop="areaId">
<el-select
v-model="dataForm.areaId"
filterable
clearable
:style="{ width: '100%' }"
@change="setAreaType"
placeholder="请选择库区名称">
<el-option
v-for="item in areaArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库区类型" prop="areaType">
<el-input
v-model="dataForm.areaType"
disabled
placeholder="库区类型" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库位名称" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入库位名称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库位编码" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入库位编码" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="type" label="库位类型">
<el-select
v-model="dataForm.type"
filterable
:style="{ width: '100%' }"
placeholder="请选择库位类型">
<el-option
v-for="item in urlOptions.dictList.dict0"
:key="item.id"
:label="item.label"
:value="parseInt(item.value)"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="排" prop="arrange">
<el-input
v-model="dataForm.arrange"
clearable
placeholder="请输入排" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="列" prop="col">
<el-input v-model="dataForm.col" clearable placeholder="请输入列" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="层" prop="layer">
<el-input v-model="dataForm.layer" clearable placeholder="请输入层" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="enabled" label="是否启用">
<el-select
v-model="dataForm.enabled"
filterable
:style="{ width: '100%' }"
placeholder="请选择是否启用">
<el-option
v-for="item in isorno"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../../mixins/basic-add';
import {
createWarehouseLocation,
updateWarehouseLocation,
getWarehouseLocation,
getCode,
} from '@/api/warehouse/warehouse-location-setup';
import { getWarehouseList } from '@/api/warehouse/warehouse-setup';
import { getWarehouseAreaList } from '@/api/warehouse/warehouse-area-setup';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
getDictList: true,
createURL: createWarehouseLocation,
updateURL: updateWarehouseLocation,
infoURL: getWarehouseLocation,
},
nameList: ['location_type'],
dataForm: {
id: undefined,
name: '',
code: '',
warehouseId: '',
areaId: '',
areaType: '',
type: '',
enabled: 1,
arrange: '',
col: '',
layer: '',
},
dataRule: {
warehouseId: [
{ required: true, message: '仓库名称不能为空', trigger: 'change' },
],
areaId: [
{ required: true, message: '库区名称不能为空', trigger: 'change' },
],
code: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
arrange: [{ required: true, message: '排不能为空', trigger: 'blur' }],
col: [{ required: true, message: '列不能为空', trigger: 'blur' }],
layer: [{ required: true, message: '层不能为空', trigger: 'blur' }],
},
warehouseArr: [],
areaArr: [],
isorno: [
{
id: 0,
name: '停用',
},
{
id: 1,
name: '启用',
},
],
typeArr: [
{
id: 1,
name: '缓存',
},
{
id: 2,
name: '活动',
},
{
id: 3,
name: '其它',
},
],
};
},
created() {
getWarehouseList().then((response) => {
this.warehouseArr = response.data;
});
getWarehouseAreaList().then((response) => {
this.areaArr = response.data;
});
},
methods: {
setAreaType() {
if (this.dataForm.areaId) {
this.dataForm.areaType = this.areaArr.find(
(item) => item.id === this.dataForm.areaId
).areaType;
}
},
},
};
</script>

View File

@ -0,0 +1,213 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<!-- 列表 -->
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:max-height="tableH"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="40%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../../mixins/basic-page';
import codeFilter from '../../mixins/code-filter';
import {
deleteWarehouseLocation,
getWarehouseLocationPage,
} from "@/api/warehouse/warehouse-location-setup";
import {
getWarehouseAreaList
} from "@/api/warehouse/warehouse-area-setup";
import {
getWarehouseList
} from "@/api/warehouse/warehouse-setup";
import tableHeightMixin from '@/mixins/tableHeightMixin';
import { publicFormatter } from '@/utils/dict';
const tableProps = [
{
prop: 'warehouseName',
label: '仓库名称',
},
{
prop: 'areaName',
label: '库区名称',
},
{
prop: 'areaType',
label: '库区类型',
},
{
prop: 'name',
label: '库位名称',
},
{
prop: 'code',
label: '库位编码',
},
{
prop: 'type',
label: '库位类型',
filter: publicFormatter('location_type')
},
{
prop: 'arrange',
label: '排',
},
{
prop: 'col',
label: '列',
},
{
prop: 'layer',
label: '层',
},
{
prop: 'enabled',
label: '是否启用',
filter: codeFilter('deactivate'),
},
];
export default {
mixins: [basicPage,tableHeightMixin],
data() {
return {
urlOptions: {
getDataListURL: getWarehouseLocationPage,
deleteURL: deleteWarehouseLocation,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`warehouse:warehouse-location-setup:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`warehouse:warehouse-location-setup:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'select',
label: '仓库',
selectOptions: [],
param: 'warehouseId',
defaultSelect: '',
filterable: true,
},
{
type: 'select',
label: '库区',
selectOptions: [],
param: 'areaId',
defaultSelect: '',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('warehouse:warehouse-location-setup:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
};
},
components: {
AddOrUpdate,
},
created() {
getWarehouseList().then((response) => {
this.formConfig[0].selectOptions = response.data;
});
getWarehouseAreaList().then((response) => {
this.formConfig[1].selectOptions = response.data;
});
},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.warehouseId = val.warehouseId;
this.listQuery.areaId = val.areaId;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 10,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -0,0 +1,126 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 13:52:10
* @LastEditors: zwq
* @LastEditTime: 2024-08-07 16:39:08
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
v-if="visible"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="仓库名称" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入仓库名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="仓库编码" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入仓库编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="enabled" label="是否启用">
<el-select
v-model="dataForm.enabled"
filterable
:style="{ width: '100%' }"
placeholder="请选择是否启用">
<el-option
v-for="item in isorno"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="type" label="仓库类型">
<el-select
v-model="dataForm.type"
filterable
:style="{ width: '100%' }"
placeholder="请选择仓库类型">
<el-option
v-for="item in urlOptions.dictList.dict0"
:key="item.id"
:label="item.label"
:value="parseInt(item.value)"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../../mixins/basic-add';
import {
createWarehouse,
updateWarehouse,
getWarehouse,
getCode,
} from '@/api/warehouse/warehouse-setup';
import { getUserProfile } from "@/api/system/user";
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
getDictList: true,
createURL: createWarehouse,
updateURL: updateWarehouse,
infoURL: getWarehouse,
},
nameList: ['warehouse_type'],
dataForm: {
id: undefined,
name: '',
code: '',
enabled: 1,
type: 2,
creator: ''
},
dataRule: {
code: [
{ required: true, message: '仓库编码不能为空', trigger: 'blur' },
],
name: [
{ required: true, message: '仓库名称不能为空', trigger: 'blur' },
],
},
isorno: [
{
id: 0,
name: '停用',
},
{
id: 1,
name: '启用',
},
],
};
},
created() {
getUserProfile().then(response => {
this.dataForm.creator = response.data.username;
});
},
methods: {},
};
</script>

View File

@ -0,0 +1,172 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<!-- 列表 -->
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:max-height="tableH"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="40%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '../../mixins/basic-page';
import { parseTime } from '../../mixins/code-filter';
import codeFilter from '../../mixins/code-filter';
import {
deleteWarehouse,
getWarehousePage,
} from "@/api/warehouse/warehouse-setup";
import tableHeightMixin from '@/mixins/tableHeightMixin';
import { publicFormatter } from '@/utils/dict';
const tableProps = [
{
prop: 'name',
label: '仓库名称',
},
{
prop: 'creator',
label: '创建人',
},
{
prop: 'createTime',
label: '创建时间',
filter: parseTime,
minWidth: 100,
},
{
prop: 'type',
label: '仓库类型',
filter: publicFormatter('warehouse_type')
},
{
prop: 'enabled',
label: '是否启用',
filter: codeFilter('deactivate'),
},
];
export default {
mixins: [basicPage,tableHeightMixin],
data() {
return {
urlOptions: {
getDataListURL: getWarehousePage,
deleteURL: deleteWarehouse,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`warehouse:warehouse-setup:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`warehouse:warehouse-setup:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'input',
label: '仓库名称',
placeholder: '仓库名称',
param: 'name',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('warehouse:warehouse-setup:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.name = val.name;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 20,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -10,7 +10,6 @@ require('echarts/theme/macarons'); // echarts theme
import resize from '@/utils/chartMixins/resize'; import resize from '@/utils/chartMixins/resize';
const animationDuration = 1000; const animationDuration = 1000;
export default { export default {
mixins: [resize], mixins: [resize],
props: { props: {
@ -38,6 +37,7 @@ export default {
data() { data() {
return { return {
chart: null, chart: null,
targetId: '',
}; };
}, },
beforeDestroy() { beforeDestroy() {
@ -50,7 +50,7 @@ export default {
methods: { methods: {
initChart() { initChart() {
this.chart = echarts.init(this.$el, 'macarons'); this.chart = echarts.init(this.$el, 'macarons');
const _this = this;
this.chart.setOption({ this.chart.setOption({
title: { title: {
text: this.title text: this.title
@ -81,6 +81,18 @@ export default {
// //
type: 'shadow', // 线'line' | 'shadow' type: 'shadow', // 线'line' | 'shadow'
}, },
formatter: function (params) {
_this.targetId = params[0].data.id;
let res =
'<div>' +
params[0].name +
'</div><br/>' +
params[0].marker +
'<div style="float:right">库存数量:' +
params[0].value +
'</div>';
return res;
},
}, },
grid: { grid: {
containLabel: true, containLabel: true,
@ -119,12 +131,36 @@ export default {
type: 'bar', type: 'bar',
barWidth: '20', barWidth: '20',
data: this.barData.map((item) => { data: this.barData.map((item) => {
return item.value; const obj = {
value: item.num,
id: item.id,
};
return obj;
}), }),
animationDuration, animationDuration,
}, },
], ],
}); });
this.chart.getZr().off('click');
this.chart.getZr().on('click', function () {
if (_this.targetId !== '') {
switch (_this.targetId) {
case 1:
_this.$router.push({
path: 'warehouse-manage1/InventoryOverview/' + _this.targetId,
});
break;
case '1818175999715164161':
_this.$router.push({
path: 'warehouse-manage2/InventoryOverview/' + _this.targetId,
});
break;
default:
console.log(_this.targetId);
break;
}
}
});
}, },
}, },
}; };

View File

@ -2,21 +2,26 @@
* @Author: zwq * @Author: zwq
* @Date: 2024-07-02 15:56:48 * @Date: 2024-07-02 15:56:48
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2024-07-02 16:55:43 * @LastEditTime: 2024-08-02 14:57:52
* @Description: * @Description:
--> -->
<template> <template>
<div class="app-container"> <div class="app-container">
<div class="flexDiv"> <div class="flexDiv">
<div v-for="i in wareName" :key="i + 'a'" class="divClass up"> <div class="divClass up">仓库名称</div>
{{ i }} <div
v-for="i in wareArr"
:key="i.id + 'a'"
class="divClass up"
:title="i.name">
{{ i.name }}
</div> </div>
</div> </div>
<div class="flexDiv"> <div class="flexDiv">
<div v-for="i in stockNum" :key="i + 'b'" class="divClass down"> <div class="divClass down">库存数量</div>
<span v-if="i === '库存数量'">{{ i }}</span> <div v-for="i in wareArr" :key="i.id + 'a'" class="divClass down">
<el-link v-else :underline="false" type="primary" @click="toPage(i)"> <el-link :underline="false" type="primary" @click="toPage(i)">
{{ i }} {{ i.num }}
</el-link> </el-link>
</div> </div>
</div> </div>
@ -25,8 +30,8 @@
ref="barChart" ref="barChart"
height="600px" height="600px"
:title="'库存数量'" :title="'库存数量'"
v-if="barData.length" v-if="wareArr.length"
:bar-data="barData" /> :bar-data="wareArr" />
<!-- 没有数据 --> <!-- 没有数据 -->
<div class="no-data-bg" v-else></div> <div class="no-data-bg" v-else></div>
</div> </div>
@ -34,37 +39,41 @@
<script> <script>
import barChart from './BarChart.vue'; import barChart from './BarChart.vue';
import { getWarehouseAllInfo } from '@/api/warehouse/warehouse-setup';
export default { export default {
data() { data() {
return { return {
wareName: ['仓库名称'], wareArr: [],
stockNum: ['库存数量'],
barData: [],
}; };
}, },
components: { components: {
barChart, barChart,
}, },
created() { created() {
for (let i = 0; i < 5; i++) { getWarehouseAllInfo().then((response) => {
this.wareName.push('仓库' + i); this.wareArr = response.data;
this.stockNum.push(i * 100 + i);
}
},
methods: {
toPage(i) {
console.log(i);
for (let i = 1; i < 6; i++) {
const obj = {
name: this.wareName[i],
value: this.stockNum[i],
};
this.barData.push(obj);
}
console.log(this.barData);
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.barChart.initChart(); this.$refs.barChart.initChart();
}); });
});
},
methods: {
toPage(i) {
switch (i.id) {
case 1:
this.$router.push({
path: 'warehouse-manage1/InventoryOverview/' + i.id,
});
break;
case '1818175999715164161':
this.$router.push({
path: 'warehouse-manage2/InventoryOverview/' + i.id,
});
break;
default:
console.log(i.id);
break;
}
}, },
}, },
}; };
@ -82,6 +91,9 @@ export default {
border: 1px solid #ededed; border: 1px solid #ededed;
font-size: 14px; font-size: 14px;
color: #606266; color: #606266;
white-space: nowrap; /* 确保文本不换行 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 使用省略号表示超出的文本 */
} }
.up:nth-child(n) { .up:nth-child(n) {
border-bottom: none; border-bottom: none;

View File

@ -0,0 +1,150 @@
<!--
* @Author: zwq
* @Date: 2023-08-22 15:01:54
* @LastEditors: zwq
* @LastEditTime: 2024-08-02 15:00:47
* @Description:
-->
<template>
<el-row :gutter="10" class="chart-container">
<el-col :span="wareType === 1 ? 14 : 24">
<div class="chart-card">
<div class="title">库存总览</div>
<div class="sub-title">
产品总数量
<div style="color: black">{{ totalNum }}</div>
</div>
<barChart
ref="barChart"
height="600px"
title="库存总览"
v-if="overviewList.length"
:histogram="overviewList" />
<!-- 没有数据 -->
<div class="no-data-bg" v-else></div>
</div>
</el-col>
<el-col :span="wareType === 1 ? 10 : 0">
<div class="chart-card">
<div class="title">库位占用率</div>
<pieChart
ref="pieChart"
height="600px"
title="库位占用率"
v-if="rateList.length"
:pie-data="rateList" />
<!-- 没有数据 -->
<div class="no-data-bg" v-else></div>
</div>
</el-col>
</el-row>
</template>
<script>
import barChart from '../../chart/BarChart.vue';
import pieChart from '../../chart/PieChart.vue';
import { getOverview, getRate } from '@/api/warehouse/warehouseLocation';
import { getWarehouse } from '@/api/warehouse/warehouse-setup';
export default {
data() {
return {
urlOptions: {
allURL: getOverview,
rateURL: getRate,
},
warehouseId: '',
wareType: 1,
totalNum: 0,
overviewList: [],
rateList: [],
};
},
components: {
barChart,
pieChart,
},
mounted() {
},
created() {
let str = this.$router.currentRoute.path;
let lastIndex = str.lastIndexOf('/');
this.warehouseId = str.slice(lastIndex + 1);
getWarehouse(this.warehouseId).then((response) => {
this.wareType = response.data.type;
this.getDataList();
});
},
methods: {
//
getDataList() {
const data = {
warehouseId: this.warehouseId,
};
this.urlOptions.allURL(data).then((response) => {
if (response.data && response.data.length) {
this.overviewList = response.data;
this.overviewList.forEach((item) => {
this.totalNum += item.num;
});
this.$nextTick(() => {
this.$refs.barChart.initChart();
});
}
});
if (this.wareType === 1) {
this.urlOptions.rateURL(data).then((response) => {
if (response.data && response.data.length) {
this.rateList = response.data;
this.$nextTick(() => {
this.$refs.pieChart.initChart();
});
}
});
}
},
},
};
</script>
<style scoped>
.chart-container {
min-height: calc(100vh - 120px - 8px);
background-color: #f0f2f7;
}
.chart-card {
min-height: calc(100vh - 120px - 8px);
background-color: #fff;
padding: 16px;
border-radius: 8px;
}
.title {
font-size: 18px;
line-height: 16px;
margin-bottom: 10px;
color: #000;
font-weight: 500;
font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
}
.title::before {
content: '';
display: inline-block;
vertical-align: top;
width: 4px;
height: 16px;
border-radius: 1px;
margin-right: 5px;
background-color: #0b58ff;
}
.sub-title {
font-size: 16px;
line-height: 18px;
color: #888686;
min-width: 80px;
text-align: center;
font-weight: 500;
margin-right: 30px;
font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
float: right;
}
</style>

View File

@ -0,0 +1,258 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 13:52:10
* @LastEditors: zwq
* @LastEditTime: 2024-08-09 10:30:18
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
v-if="visible"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="仓库名称" prop="warehouseName">
<el-input
v-model="dataForm.warehouseName"
readonly
placeholder="请输入仓库名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="库区名称" prop="warehouseAreaId">
<el-select
v-model="dataForm.warehouseAreaId"
filterable
:style="{ width: '100%' }"
:disabled="dataForm.id ? true : false"
placeholder="请选择库区名称">
<el-option
v-for="item in warehouseAreaArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物品名称" prop="goodsId">
<el-select
v-model="dataForm.goodsId"
filterable
clearable
:disabled="dataForm.id ? true : false"
:style="{ width: '100%' }"
@change="setGoodInfo"
placeholder="请选择物品名称">
<el-option
v-for="item in goodsArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物品编码" prop="code">
<el-input
v-model="dataForm.code"
readonly
placeholder="请输入物品编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物品规格" prop="specifications">
<el-input
v-model="dataForm.specifications"
readonly
placeholder="请输入物品规格" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物品批次" prop="goodsBatch">
<el-input
v-if="!dataForm.id ? true : false"
v-model="dataForm.goodsBatch"
clearable
placeholder="请输入物品批次" />
<el-select
v-else
v-model="dataForm.goodsBatch"
filterable
clearable
style="width: 100%"
placeholder="请选择物品名称">
<el-option
v-for="(item, index) in Batch"
:key="index"
:label="item.goodsBatch"
:value="item.goodsBatch"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="dataForm.id ? '出库数量' : '入库数量'"
prop="numDet">
<el-input-number
v-model="dataForm.numDet"
clearable
style="width: 100%"
:min="0"
placeholder="请输入数量" />
<!-- :max="max?max:9999999" -->
</el-form-item>
</el-col>
<el-col :span="12" v-if="!dataForm.id ? true : false">
<el-form-item label="供应商" prop="supplierId">
<el-select
v-model="dataForm.supplierId"
filterable
disabled
:style="{ width: '100%' }"
placeholder="请选择供应商">
<el-option
v-for="item in supplierArr"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../../mixins/basic-add';
import {
createWarehouseRealtime,
outWarehouseRealtime,
getWarehouseRealtime,
getWarehouseRealtimeDet,
} from '@/api/warehouse/warehouseRealtime';
import { getWarehouse } from '@/api/warehouse/warehouse-setup';
import { getWarehouseAreaList } from '@/api/warehouse/warehouse-area-setup';
import { getMaterialList, getSupplierList } from '@/api/base/material';
import { mapGetters } from 'vuex';
export default {
mixins: [basicAdd],
computed: {
...mapGetters(['nickname']),
},
data() {
return {
urlOptions: {
getOption: true,
createURL: createWarehouseRealtime,
updateURL: outWarehouseRealtime,
infoURL: getWarehouseRealtime,
},
dataForm: {
id: undefined,
warehouseName: '',
warehouseId: '',
warehouseAreaId: '',
goodsId: '',
code: '',
specifications: '',
goodsBatch: '',
numDet: '',
operator: '',
supplierId: '',
},
goodsArr: [], //
Batch: [], //
warehouseAreaArr: [], //
supplierArr: [], //
//max: 0,
dataRule: {
goodsId: [
{ required: true, message: '物品名称不能为空', trigger: 'change' },
],
warehouseAreaId: [
{ required: true, message: '库区名称不能为空', trigger: 'change' },
],
goodsBatch: [
{
required: true,
message: '物品批次不能为空,若无请填写无',
trigger: 'blur',
},
],
numDet: [{ required: true, message: '数量不能为空', trigger: 'blur' }],
},
};
},
created() {},
methods: {
init(warehouseId) {
this.dataForm.warehouseId = warehouseId || '';
this.dataForm.id = undefined;
this.visible = true;
this.dataForm.operator = this.nickname;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
this.getArr();
});
},
getArr() {
getWarehouse(this.dataForm.warehouseId).then((response) => {
this.dataForm.warehouseName = response.data.name;
});
getMaterialList().then((response) => {
this.goodsArr = response.data;
});
getSupplierList().then((res) => {
this.supplierArr = res.data;
});
getWarehouseAreaList(this.dataForm.warehouseId).then((response) => {
this.warehouseAreaArr = response.data;
});
},
setGoodInfo() {
this.goodsArr.forEach((item) => {
if (item.id === this.dataForm.goodsId) {
this.dataForm.code = item.code;
this.dataForm.specifications = item.specifications;
this.dataForm.supplierId = item.supplierId;
}
});
},
// setBatchInfo(){
// this.Batch.forEach((item) => {
// if (item.goodsBatch === this.dataForm.goodsBatch) {
// this.max = item.numDet
// }
// });
// },
outWare(data) {
this.dataForm.warehouseId = data.warehouseId;
this.getArr();
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
this.dataForm.realTimeId = data.id;
this.dataForm.warehouseAreaId = data.warehouseAreaId;
this.dataForm.warehouseAreaId = data.warehouseAreaId;
this.dataForm.id = data.id;
this.dataForm.goodsId = data.goodsId;
this.dataForm.code = data.code;
this.dataForm.specifications = data.spec;
getWarehouseRealtimeDet(data.id).then((res) => {
this.Batch = res.data;
});
// this.urlOptions.infoURL(data.id).then((response) => {
// this.dataForm = response.data;
// });
});
},
},
};
</script>

Some files were not shown because too many files have changed in this diff Show More