样式修改

dev_招标
yewj 4 weeks ago
parent 6cc31cfde5
commit 1155b55c9a

@ -0,0 +1,7 @@
<svg t="1709457490982" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7187" width="200" height="200">
<path d="M768 896H256a85.333333 85.333333 0 0 1-85.333333-85.333333V213.333333a85.333333 85.333333 0 0 1 85.333333-85.333333h512a85.333333 85.333333 0 0 1 85.333333 85.333333v597.333334a85.333333 85.333333 0 0 1-85.333333 85.333333z" fill="#FFE8E6" p-id="7188"></path>
<path d="M682.666667 213.333333H341.333333a32 32 0 0 1 0-64h341.333334a32 32 0 0 1 0 64zM682.666667 341.333333H341.333333a32 32 0 0 1 0-64h341.333334a32 32 0 0 1 0 64zM512 469.333333H341.333333a32 32 0 0 1 0-64h170.666667a32 32 0 0 1 0 64z" fill="#F56C6C" p-id="7189"></path>
<path d="M512 661.333333m-149.333333 0a149.333333 149.333333 0 1 0 298.666666 0 149.333333 149.333333 0 1 0-298.666666 0Z" fill="#FFE8E6" p-id="7190"></path>
<path d="M512 682.666667a32 32 0 0 1-32-32v-74.666667a32 32 0 0 1 64 0v74.666667a32 32 0 0 1-32 32zM512 768a32 32 0 1 1 0-64 32 32 0 0 1 0 64z" fill="#F56C6C" p-id="7191"></path>
<path d="M768 896H256a85.333333 85.333333 0 0 1-85.333333-85.333333V213.333333a85.333333 85.333333 0 0 1 85.333333-85.333333h512a85.333333 85.333333 0 0 1 85.333333 85.333333v597.333334a85.333333 85.333333 0 0 1-85.333333 85.333333zM256 192a21.333333 21.333333 0 0 0-21.333333 21.333333v597.333334a21.333333 21.333333 0 0 0 21.333333 21.333333h512a21.333333 21.333333 0 0 0 21.333333-21.333333V213.333333a21.333333 21.333333 0 0 0-21.333333-21.333333H256z" fill="#F56C6C" p-id="7192"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,7 @@
<svg t="1709457444982" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6187" width="200" height="200">
<path d="M853.333333 938.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334V170.666667a85.333333 85.333333 0 0 1 85.333334-85.333334h682.666666a85.333333 85.333333 0 0 1 85.333334 85.333334v682.666666a85.333333 85.333333 0 0 1-85.333334 85.333334z" fill="#FFE8E6" p-id="6188"></path>
<path d="M512 640m-256 0a256 256 0 1 0 512 0 256 256 0 1 0-512 0Z" fill="#FFE8E6" p-id="6189"></path>
<path d="M512 661.333333a32 32 0 0 1-32-32V341.333333a32 32 0 0 1 64 0v288a32 32 0 0 1-32 32z" fill="#F56C6C" p-id="6190"></path>
<path d="M656 517.333333H368a32 32 0 0 1 0-64h288a32 32 0 0 1 0 64z" fill="#F56C6C" p-id="6191"></path>
<path d="M853.333333 938.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334V170.666667a85.333333 85.333333 0 0 1 85.333334-85.333334h682.666666a85.333333 85.333333 0 0 1 85.333334 85.333334v682.666666a85.333333 85.333333 0 0 1-85.333334 85.333334zM170.666667 149.333333a21.333333 21.333333 0 0 0-21.333334 21.333334v682.666666a21.333333 21.333333 0 0 0 21.333334 21.333334h682.666666a21.333333 21.333333 0 0 0 21.333334-21.333334V170.666667a21.333333 21.333333 0 0 0-21.333334-21.333334H170.666667z" fill="#F56C6C" p-id="6192"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,6 @@
<svg t="1709457383982" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5187" width="200" height="200">
<path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64c-200.298667 0-362.666667 162.368-362.666667 362.666667s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667-162.368-362.666667-362.666667-362.666667z" fill="#1890ff" p-id="5188"></path>
<path d="M512 298.666667c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333333-213.333333 95.509333-213.333333 213.333333-213.333333z m0 64a149.333333 149.333333 0 1 0 0 298.666666 149.333333 149.333333 0 0 0 0-298.666666z" fill="#1890ff" p-id="5189"></path>
<path d="M512 405.333333a32 32 0 0 1 32 32v160a32 32 0 0 1-64 0v-160a32 32 0 0 1 32-32z" fill="#1890ff" p-id="5190"></path>
<path d="M405.333333 512a32 32 0 0 1 32-32h160a32 32 0 0 1 0 64h-160a32 32 0 0 1-32-32z" fill="#1890ff" p-id="5191"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -165,19 +165,21 @@
// //
.el-card { .el-card {
border-radius: $base-border-radius; border-radius: $base-border-radius;
box-shadow: $base-box-shadow; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
transition: $base-transition; transition: $base-transition;
border: none; border: none;
overflow: hidden;
&:hover { &:hover {
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.1); box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.1);
transform: translateY(-2px); transform: translateY(-4px);
} }
.el-card__header { .el-card__header {
padding: 16px 20px; padding: 16px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05); border-bottom: 1px solid rgba(0, 0, 0, 0.05);
font-weight: 500; font-weight: 500;
background-color: rgba($blue, 0.02);
} }
.el-card__body { .el-card__body {
@ -185,6 +187,96 @@
} }
} }
//
.app-card {
border-radius: $base-border-radius;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
background-color: #fff;
transition: $base-transition;
margin-bottom: 20px;
overflow: hidden;
&:hover {
box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.1);
transform: translateY(-4px);
}
.app-card__header {
padding: 16px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
font-weight: 500;
display: flex;
align-items: center;
justify-content: space-between;
background-color: rgba($blue, 0.02);
.app-card__title {
font-size: 16px;
color: #303133;
font-weight: 500;
display: flex;
align-items: center;
.icon {
margin-right: 8px;
color: $blue;
}
}
.app-card__extra {
color: #909399;
}
}
.app-card__body {
padding: 20px;
}
.app-card__footer {
padding: 10px 20px;
border-top: 1px solid rgba(0, 0, 0, 0.05);
background-color: rgba($blue, 0.01);
}
&.is-shadow-none {
box-shadow: none;
&:hover {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}
}
&.is-hover-none {
&:hover {
transform: none;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}
}
&.is-border {
border: 1px solid #ebeef5;
}
&.is-gradient-header {
.app-card__header {
background: $primary-gradient;
color: #fff;
.app-card__title {
color: #fff;
.icon {
color: #fff;
}
}
.app-card__extra {
color: rgba(255, 255, 255, 0.8);
}
}
}
}
// //
.el-form { .el-form {
.el-form-item { .el-form-item {
@ -209,6 +301,32 @@
.el-table { .el-table {
border-radius: $base-border-radius; border-radius: $base-border-radius;
overflow: hidden; overflow: hidden;
height: 500px; //
//
.el-table__body-wrapper {
height: calc(100% - 40px); //
overflow-y: auto;
//
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, 0.3);
border-radius: 4px;
&:hover {
background-color: rgba(144, 147, 153, 0.5);
}
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
th { th {
background-color: $background-light; background-color: $background-light;
@ -217,17 +335,123 @@
td, th { td, th {
padding: 12px 0; padding: 12px 0;
height: 40px; //
line-height: 1.5;
box-sizing: border-box;
} }
.el-table__row { .el-table__row {
transition: $base-transition; transition: $base-transition;
height: 40px; //
&:hover { &:hover {
background-color: rgba($blue, 0.04); background-color: rgba($blue, 0.04);
} }
//
td {
vertical-align: middle;
//
.cell {
display: flex;
align-items: center;
height: 100%;
line-height: 1.2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
//
}
}
} }
.el-table--striped .el-table__body tr.el-table__row--striped td { &.el-table--striped .el-table__body tr.el-table__row--striped td {
background-color: rgba($blue, 0.02); background-color: #eef0f5 !important;
}
//
.el-table__fixed, .el-table__fixed-right {
height: 100% !important;
.el-table__fixed-body-wrapper {
height: calc(100% - 40px) !important; //
}
}
//
.el-table__empty-block {
height: 100%;
min-height: 200px;
}
}
//
.el-table--small {
height: 400px;
.el-table__body-wrapper,
.el-table__fixed-body-wrapper {
height: calc(100% - 36px) !important; //
}
}
.el-table--medium {
height: 500px;
}
.el-table--large {
height: 600px;
}
//
.el-table--h300 { height: 300px; }
.el-table--h400 { height: 400px; }
.el-table--h500 { height: 500px; }
.el-table--h600 { height: 600px; }
.el-table--h700 { height: 700px; }
.el-table--h800 { height: 800px; }
//
.el-table--auto-height {
height: 100%;
.el-table__body-wrapper,
.el-table__fixed-body-wrapper {
height: calc(100% - 40px) !important;
} }
}
//
.el-table--row-small {
td, th, .el-table__row {
height: 40px;
}
}
.el-table--row-medium {
td, th, .el-table__row {
height: 50px;
}
}
.el-table--row-large {
td, th, .el-table__row {
height: 60px;
}
}
//
.el-table--row-h30 {
td, th, .el-table__row { height: 30px; }
}
.el-table--row-h40 {
td, th, .el-table__row { height: 40px; }
}
.el-table--row-h50 {
td, th, .el-table__row { height: 50px; }
}
.el-table--row-h60 {
td, th, .el-table__row { height: 60px; }
} }

@ -4,6 +4,9 @@
@import './element-ui.scss'; @import './element-ui.scss';
@import './sidebar.scss'; @import './sidebar.scss';
@import './btn.scss'; @import './btn.scss';
@import './ruoyi.scss';
@import './list-page.scss';
@import './tag.scss';
body { body {
height: 100%; height: 100%;

@ -0,0 +1,254 @@
/*
*
*
*/
/* 列表页面卡片样式 */
.list-card {
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
margin-bottom: 16px;
transition: all 0.3s;
&:hover {
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.1);
}
.el-card__header {
padding: 16px 20px;
border-bottom: 1px solid #f0f0f0;
font-weight: 600;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.el-card__body {
padding: 16px 20px;
}
}
/* 搜索表单样式 */
.search-form {
.el-form-item {
margin-bottom: 16px;
.el-form-item__label {
font-weight: 500;
color: #606266;
}
.el-input, .el-select, .el-date-editor {
width: 100%;
.el-input__inner {
border-radius: 4px;
transition: all 0.3s;
&:hover, &:focus {
border-color: #1890ff;
}
}
}
}
}
/* 操作按钮组样式 */
.action-group {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.left-actions, .right-actions {
display: flex;
gap: 8px;
}
.el-button {
border-radius: 4px;
transition: all 0.3s;
&.el-button--primary {
background-color: #1890ff;
border-color: #1890ff;
&:hover, &:focus {
background-color: #40a9ff;
border-color: #40a9ff;
}
}
&.el-button--success {
background-color: #52c41a;
border-color: #52c41a;
&:hover, &:focus {
background-color: #73d13d;
border-color: #73d13d;
}
}
&.el-button--danger {
background-color: #f5222d;
border-color: #f5222d;
&:hover, &:focus {
background-color: #ff4d4f;
border-color: #ff4d4f;
}
}
&.el-button--warning {
background-color: #faad14;
border-color: #faad14;
&:hover, &:focus {
background-color: #ffc53d;
border-color: #ffc53d;
}
}
}
}
/* 表格样式 */
.list-table {
width: 100%;
border-radius: 4px;
overflow: hidden;
.el-table__header-wrapper th {
background-color: #fafafa;
color: #262626;
font-weight: 600;
height: 48px;
padding: 8px 16px;
border-bottom: 1px solid #f0f0f0;
}
.el-table__body-wrapper td {
padding: 12px 16px;
border-bottom: 1px solid #f0f0f0;
}
.el-table__row {
transition: all 0.3s;
&:hover {
background-color: #f5f7fa;
}
&.current-row {
background-color: #e6f7ff;
}
}
.el-table__empty-block {
min-height: 200px;
.el-table__empty-text {
color: #8c8c8c;
}
}
.operation-column {
.el-button {
padding: 4px 8px;
& + .el-button {
margin-left: 8px;
}
}
}
}
/* 分页样式 */
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 16px;
.el-pagination {
padding: 0;
font-weight: normal;
.btn-prev, .btn-next {
border: 1px solid #d9d9d9;
border-radius: 4px;
&:hover {
color: #1890ff;
border-color: #1890ff;
}
}
.el-pager li {
border: 1px solid #d9d9d9;
border-radius: 4px;
margin: 0 4px;
&:hover {
color: #1890ff;
border-color: #1890ff;
}
&.active {
background-color: #1890ff;
color: #fff;
border-color: #1890ff;
}
}
.el-pagination__sizes {
margin-right: 16px;
}
}
}
/* 响应式适配 */
@media (max-width: 768px) {
.search-form {
.el-form-item {
width: 100%;
}
}
.action-group {
flex-direction: column;
align-items: flex-start;
.left-actions, .right-actions {
width: 100%;
margin-bottom: 8px;
}
}
.list-table {
.el-table__header-wrapper th {
padding: 8px;
}
.el-table__body-wrapper td {
padding: 8px;
}
}
}
/* 动画效果 */
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.slide-enter-active, .slide-leave-active {
transition: all 0.3s;
}
.slide-enter, .slide-leave-to {
transform: translateY(20px);
opacity: 0;
}

@ -136,7 +136,7 @@
} }
.el-table__body tr.current-row > td { .el-table__body tr.current-row > td {
background-color: #f3d5d5; background-color: #d7e4de;
} }
} }

@ -0,0 +1,321 @@
/*
*
*
*/
//
.el-tag {
display: inline-flex;
align-items: center;
justify-content: center;
height: auto;
padding: 0 10px;
font-size: 16px;
line-height: 24px;
border-radius: 4px;
font-weight: 600;
white-space: nowrap;
border: none;
transition: all 0.3s;
margin-right: 8px;
//
.el-tag__close {
color: inherit;
opacity: 0.6;
top: 0;
right: -5px;
&:hover {
background-color: transparent;
color: inherit;
opacity: 1;
}
}
//
&.el-tag--small {
height: 20px;
padding: 0 8px;
font-size: 12px;
line-height: 20px;
}
//
&.el-tag--mini {
height: 16px;
padding: 10px;
font-size: 11px;
line-height: 16px;
}
//
&.el-tag--medium {
height: 28px;
padding: 0 12px;
font-size: 14px;
line-height: 28px;
}
}
//
.el-tag {
background-color: #f5f5f5;
color: #666;
&:hover {
background-color: #e8e8e8;
}
}
//
.el-tag--primary {
background-color: #e6f7ff;
color: #1890ff;
&:hover {
background-color: #bae7ff;
}
}
// 绿
.el-tag--success {
background-color: #f6ffed;
color: #52c41a;
&:hover {
background-color: #d9f7be;
}
}
//
.el-tag--info {
background-color: #f4f4f5;
color: #909399;
&:hover {
background-color: #e9e9eb;
}
}
//
.el-tag--warning {
background-color: #fffbe6;
color: #faad14;
&:hover {
background-color: #fff1b8;
}
}
//
.el-tag--danger {
background-color: #fff2f0;
color: #f5222d;
&:hover {
background-color: #ffccc7;
}
}
//
.el-tag.el-tag--dark {
color: white;
&.el-tag--primary {
background-color: #1890ff;
&:hover {
background-color: #40a9ff;
}
}
&.el-tag--success {
background-color: #52c41a;
&:hover {
background-color: #73d13d;
}
}
&.el-tag--info {
background-color: #909399;
&:hover {
background-color: #a6a9ad;
}
}
&.el-tag--warning {
background-color: #faad14;
&:hover {
background-color: #ffc53d;
}
}
&.el-tag--danger {
background-color: #f5222d;
&:hover {
background-color: #ff4d4f;
}
}
}
//
.el-tag.el-tag--plain {
background-color: transparent;
border: 1px solid;
&.el-tag--primary {
color: #1890ff;
border-color: #91caff;
&:hover {
background-color: rgba(24, 144, 255, 0.05);
}
}
&.el-tag--success {
color: #52c41a;
border-color: #b7eb8f;
&:hover {
background-color: rgba(82, 196, 26, 0.05);
}
}
&.el-tag--info {
color: #909399;
border-color: #d3d4d6;
&:hover {
background-color: rgba(144, 147, 153, 0.05);
}
}
&.el-tag--warning {
color: #faad14;
border-color: #ffe58f;
&:hover {
background-color: rgba(250, 173, 20, 0.05);
}
}
&.el-tag--danger {
color: #f5222d;
border-color: #ffa39e;
&:hover {
background-color: rgba(245, 34, 45, 0.05);
}
}
}
//
.el-tag-with-icon {
.el-icon {
margin-right: 4px;
font-size: 12px;
}
}
//
.el-tag-clickable {
cursor: pointer;
&:hover {
opacity: 0.85;
}
&:active {
opacity: 0.7;
}
}
//
.el-tag-rounded {
border-radius: 16px;
}
//
.el-tag-bordered {
border: 1px solid;
&.el-tag--primary {
border-color: #91caff;
}
&.el-tag--success {
border-color: #b7eb8f;
}
&.el-tag--info {
border-color: #d3d4d6;
}
&.el-tag--warning {
border-color: #ffe58f;
}
&.el-tag--danger {
border-color: #ffa39e;
}
}
//
.status-tag {
padding-left: 18px;
position: relative;
&::before {
content: '';
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
width: 6px;
height: 6px;
border-radius: 50%;
background-color: currentColor;
}
}
//
.el-tag {
transition: all 0.3s;
&.fade-enter-active, &.fade-leave-active {
transition: opacity 0.3s;
}
&.fade-enter, &.fade-leave-to {
opacity: 0;
}
}
//
.el-tag-group {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
.el-tag {
margin-right: 0;
}
}
//
@media (max-width: 768px) {
.el-tag {
font-size: 11px;
padding: 0 8px;
&.el-tag--medium {
padding: 0 10px;
}
}
}

@ -290,6 +290,7 @@
<el-table <el-table
v-loading="loading" v-loading="loading"
:data="list" :data="list"
stripe
style="width: 100%" style="width: 100%"
border border
key="1" key="1"

@ -0,0 +1,293 @@
<template>
<div class="app-container">
<h2>卡片组件样式展示</h2>
<p class="text-muted mb-4">这个页面展示了系统中可用的卡片样式和组件</p>
<el-divider content-position="left">Element UI 卡片</el-divider>
<el-row :gutter="20">
<el-col :span="8">
<el-card class="mb-4">
<div slot="header" class="clearfix">
<span>基础卡片</span>
<el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>
</div>
<div>
这是一个基础的 Element UI 卡片示例展示了标准的卡片样式
卡片可用于容纳文字列表表单等内容
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="mb-4">
<div slot="header" class="clearfix">
<span>数据展示卡片</span>
</div>
<div class="text-center">
<div style="font-size: 36px; font-weight: bold; color: #1890ff;">256</div>
<div class="text-muted mt-2">今日访问量</div>
<el-progress :percentage="68" :color="customColors" class="mt-3"></el-progress>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="mb-4">
<div slot="header" class="clearfix">
<span>列表卡片</span>
</div>
<div>
<div v-for="(item, index) in 4" :key="index" class="card-list-item">
<div class="card-list-item-title">列表项 {{ item }}</div>
<div class="card-list-item-desc text-muted">这是列表项 {{ item }} 的描述信息</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-divider content-position="left">自定义卡片</el-divider>
<el-row :gutter="20">
<el-col :span="8">
<div class="app-card mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-data icon"></i>
基础自定义卡片
</div>
<div class="app-card__extra">
<el-button type="text" size="small">更多</el-button>
</div>
</div>
<div class="app-card__body">
这是一个自定义卡片组件具有更好的视觉效果和交互体验
悬停时会有上浮动画和阴影加深效果
</div>
</div>
</el-col>
<el-col :span="8">
<div class="app-card is-gradient-header mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-finance icon"></i>
渐变标题卡片
</div>
<div class="app-card__extra">
<el-button type="text" size="small" style="color: white;">查看</el-button>
</div>
</div>
<div class="app-card__body">
这个卡片使用了渐变色标题更加醒目和现代化
适合用于重要信息或数据的展示
</div>
</div>
</el-col>
<el-col :span="8">
<div class="app-card mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-order icon"></i>
带页脚的卡片
</div>
<div class="app-card__extra">
<el-tag size="small" type="success"></el-tag>
</div>
</div>
<div class="app-card__body">
这个卡片包含了页脚部分可以放置额外的操作按钮或信息
页脚与内容区域有明显的分隔
</div>
<div class="app-card__footer">
<el-button type="primary" size="small">确认</el-button>
<el-button size="small">取消</el-button>
</div>
</div>
</el-col>
</el-row>
<el-divider content-position="left">卡片变体</el-divider>
<el-row :gutter="20">
<el-col :span="6">
<div class="app-card is-border mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-grid icon"></i>
边框卡片
</div>
</div>
<div class="app-card__body">
使用边框而不是阴影来区分卡片
</div>
</div>
</el-col>
<el-col :span="6">
<div class="app-card is-shadow-none is-border mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-shop icon"></i>
无阴影卡片
</div>
</div>
<div class="app-card__body">
没有阴影效果的简洁卡片
</div>
</div>
</el-col>
<el-col :span="6">
<div class="app-card is-hover-none mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-marketing icon"></i>
无悬停效果
</div>
</div>
<div class="app-card__body">
悬停时没有上浮效果的卡片
</div>
</div>
</el-col>
<el-col :span="6">
<div class="app-card card-hover-effect mb-4" style="background: linear-gradient(45deg, #1890ff, #36cfc9);">
<div class="app-card__body" style="color: white; text-align: center; padding: 30px 20px;">
<i class="el-icon-star-on" style="font-size: 36px;"></i>
<div style="margin-top: 10px; font-size: 16px;">特殊效果卡片</div>
</div>
</div>
</el-col>
</el-row>
<el-divider content-position="left">实用卡片布局</el-divider>
<el-row :gutter="20">
<el-col :span="16">
<div class="app-card mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-data icon"></i>
数据统计
</div>
<div class="app-card__extra">
<el-radio-group v-model="timeRange" size="small">
<el-radio-button label="today">今日</el-radio-button>
<el-radio-button label="week">本周</el-radio-button>
<el-radio-button label="month">本月</el-radio-button>
</el-radio-group>
</div>
</div>
<div class="app-card__body" style="height: 300px; display: flex; align-items: center; justify-content: center;">
<div style="text-align: center; color: #909399;">
<i class="el-icon-data-line" style="font-size: 48px;"></i>
<div style="margin-top: 10px;">此处放置图表组件</div>
</div>
</div>
</div>
</el-col>
<el-col :span="8">
<div class="app-card mb-4">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-s-opportunity icon"></i>
快速操作
</div>
</div>
<div class="app-card__body">
<el-button type="primary" icon="el-icon-plus" class="mb-3 w-100">新增数据</el-button>
<el-button type="success" icon="el-icon-upload" class="mb-3 w-100">导入数据</el-button>
<el-button type="warning" icon="el-icon-download" class="mb-3 w-100">导出报表</el-button>
<el-button type="info" icon="el-icon-refresh" class="w-100">刷新缓存</el-button>
</div>
</div>
<div class="app-card">
<div class="app-card__header">
<div class="app-card__title">
<i class="el-icon-bell icon"></i>
通知公告
</div>
<div class="app-card__extra">
<el-button type="text" size="small">全部</el-button>
</div>
</div>
<div class="app-card__body" style="padding: 0;">
<div v-for="(item, index) in 3" :key="index"
style="padding: 12px 20px; border-bottom: 1px solid #f0f0f0;">
<div style="font-weight: 500;">系统更新通知 {{ item }}</div>
<div class="text-muted" style="font-size: 12px; margin-top: 5px;">2023-03-0{{ item }} 10:00</div>
</div>
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'CardDemo',
data() {
return {
timeRange: 'today',
customColors: [
{color: '#f56c6c', percentage: 20},
{color: '#e6a23c', percentage: 40},
{color: '#5cb87a', percentage: 60},
{color: '#1989fa', percentage: 80},
{color: '#6f7ad3', percentage: 100}
]
}
}
}
</script>
<style lang="scss" scoped>
.mb-4 {
margin-bottom: 16px;
}
.mt-2 {
margin-top: 8px;
}
.mt-3 {
margin-top: 12px;
}
.w-100 {
width: 100%;
}
.text-center {
text-align: center;
}
.text-muted {
color: #909399;
}
.card-list-item {
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.card-list-item-title {
font-weight: 500;
margin-bottom: 5px;
}
.card-list-item-desc {
font-size: 12px;
}
}
</style>

@ -0,0 +1,241 @@
<template>
<div class="app-container">
<el-card class="list-card">
<div slot="header">
<span>标签样式示例</span>
</div>
<div class="section">
<h3>基础标签</h3>
<div class="example-row">
<el-tag>默认标签</el-tag>
<el-tag type="primary">主要标签</el-tag>
<el-tag type="success">成功标签</el-tag>
<el-tag type="info">信息标签</el-tag>
<el-tag type="warning">警告标签</el-tag>
<el-tag type="danger">危险标签</el-tag>
</div>
</div>
<div class="section">
<h3>深色标签</h3>
<div class="example-row">
<el-tag effect="dark">默认标签</el-tag>
<el-tag type="primary" effect="dark">主要标签</el-tag>
<el-tag type="success" effect="dark">成功标签</el-tag>
<el-tag type="info" effect="dark">信息标签</el-tag>
<el-tag type="warning" effect="dark">警告标签</el-tag>
<el-tag type="danger" effect="dark">危险标签</el-tag>
</div>
</div>
<div class="section">
<h3>朴素标签</h3>
<div class="example-row">
<el-tag effect="plain">默认标签</el-tag>
<el-tag type="primary" effect="plain">主要标签</el-tag>
<el-tag type="success" effect="plain">成功标签</el-tag>
<el-tag type="info" effect="plain">信息标签</el-tag>
<el-tag type="warning" effect="plain">警告标签</el-tag>
<el-tag type="danger" effect="plain">危险标签</el-tag>
</div>
</div>
<div class="section">
<h3>可关闭标签</h3>
<div class="example-row">
<el-tag closable>默认标签</el-tag>
<el-tag type="primary" closable>主要标签</el-tag>
<el-tag type="success" closable>成功标签</el-tag>
<el-tag type="info" closable>信息标签</el-tag>
<el-tag type="warning" closable>警告标签</el-tag>
<el-tag type="danger" closable>危险标签</el-tag>
</div>
</div>
<div class="section">
<h3>不同尺寸</h3>
<div class="example-row">
<el-tag size="mini" type="primary">迷你标签</el-tag>
<el-tag size="small" type="success">小型标签</el-tag>
<el-tag type="warning">默认标签</el-tag>
<el-tag size="medium" type="danger">中等标签</el-tag>
</div>
</div>
<div class="section">
<h3>自定义类名</h3>
<div class="example-row">
<el-tag class="el-tag-rounded" type="primary">圆角标签</el-tag>
<el-tag class="el-tag-bordered" type="success">带边框标签</el-tag>
<el-tag class="el-tag-with-icon" type="warning">
<i class="el-icon-star-on"></i>带图标标签
</el-tag>
<el-tag class="el-tag-clickable" type="danger" @click="handleClick"></el-tag>
</div>
</div>
<div class="section">
<h3>状态标签</h3>
<div class="example-row">
<el-tag class="status-tag" type="primary">处理中</el-tag>
<el-tag class="status-tag" type="success">已完成</el-tag>
<el-tag class="status-tag" type="warning">待审核</el-tag>
<el-tag class="status-tag" type="danger">已拒绝</el-tag>
<el-tag class="status-tag" type="info">已关闭</el-tag>
</div>
</div>
<div class="section">
<h3>标签组</h3>
<div class="el-tag-group">
<el-tag type="primary">标签1</el-tag>
<el-tag type="success">标签2</el-tag>
<el-tag type="warning">标签3</el-tag>
<el-tag type="danger">标签4</el-tag>
</div>
</div>
<div class="section">
<h3>动态编辑标签</h3>
<div class="example-row">
<el-tag
v-for="tag in dynamicTags"
:key="tag"
closable
type="primary"
@close="handleClose(tag)"
>
{{ tag }}
</el-tag>
<el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ </el-button>
</div>
</div>
<div class="section">
<h3>在表格中使用</h3>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="status" label="状态">
<template slot-scope="scope">
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.statusText }}</el-tag>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
</div>
</template>
<script>
export default {
name: "TagExample",
data() {
return {
dynamicTags: ['标签一', '标签二', '标签三'],
inputVisible: false,
inputValue: '',
tableData: [
{
date: '2025-03-04',
name: '张三',
status: 'success',
statusText: '已完成'
},
{
date: '2025-03-03',
name: '李四',
status: 'warning',
statusText: '待审核'
},
{
date: '2025-03-02',
name: '王五',
status: 'primary',
statusText: '处理中'
},
{
date: '2025-03-01',
name: '赵六',
status: 'danger',
statusText: '已拒绝'
}
]
};
},
methods: {
handleClose(tag) {
this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
},
showInput() {
this.inputVisible = true;
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus();
});
},
handleInputConfirm() {
let inputValue = this.inputValue;
if (inputValue) {
this.dynamicTags.push(inputValue);
}
this.inputVisible = false;
this.inputValue = '';
},
handleClick() {
this.$message.success('点击了标签');
}
},
filters: {
statusFilter(status) {
return status;
}
}
};
</script>
<style lang="scss" scoped>
.section {
margin-bottom: 24px;
h3 {
margin-top: 0;
margin-bottom: 16px;
font-size: 16px;
font-weight: 600;
color: #333;
}
.example-row {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: center;
margin-bottom: 8px;
}
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
.button-new-tag {
margin-left: 10px;
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
</style>

@ -1,210 +1,149 @@
<template> <template>
<div class="app-container home"> <div class="app-container home">
<div> <div class="welcome-section">
<h2>欢迎使用供应商自助管理系统</h2> <!-- <h2 class="welcome-title">欢迎使用供应商自助管理系统</h2> -->
<el-divider/> <el-divider class="welcome-divider"/>
</div> </div>
<!-- 分割线 -->
<div class="mt10 grid-container grid-container3" style="height: 15%"> <!-- 数据概览卡片 -->
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:product']"> <div class="dashboard-cards">
<el-row> <el-row :gutter="20">
<div class="height-full fl center ml20" style="width: 30%"> <el-col :xs="24" :sm="8" :md="8" :lg="8" v-hasPermi="['home:index:product']">
<el-image style="border-radius: 4%;width: 80%;height: 80%" <el-card class="data-card" shadow="hover">
:src="productSvg"> <div class="card-content">
<div slot="placeholder" class="image-slot"> <div class="card-icon">
加载中<span class="dot">...</span> <el-image class="icon-image" :src="productSvg"></el-image>
</div> </div>
</el-image> <div class="card-info">
</div> <div class="card-title">已对照产品</div>
<div class="height-full fr center mr20"> <div class="card-value">{{ productCount }}</div>
<span class="header d-block">
已对照产品
</span>
<span class="d-block mt10" :style="{'font-size': '32px','font-weight': 'bolder',color:'#394047'}">
{{ productCount }}
</span>
</div>
</el-row>
</el-card>
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:invWarn']">
<el-row>
<div class="height-full fl center ml20" style="width: 30%">
<el-image style="border-radius: 4%;width: 80%;height: 80%"
:src="invSvg">
<div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span>
</div> </div>
</el-image> </div>
</div> </el-card>
<div class="height-full fr center mr20" @click="linkPage('/remind/invRemindMsg')"> </el-col>
<span class="header d-block">
库存预警 <el-col :xs="24" :sm="8" :md="8" :lg="8" v-hasPermi="['home:index:invWarn']">
</span> <el-card class="data-card warning-card" shadow="hover" @click.native="linkPage('/remind/invRemindMsg')">
<span class="d-block mt10" :style="{'font-size': '32px','font-weight': 'bolder',color:'#FF0000'}"> <div class="card-content">
{{ invMsgCount }} <div class="card-icon">
</span> <el-image class="icon-image" :src="invSvg"></el-image>
</div> </div>
</el-row> <div class="card-info">
</el-card> <div class="card-title">库存预警</div>
<div class="card-value warning-value">{{ invMsgCount }}</div>
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:certWarn']"> </div>
<el-row> </div>
<div class="height-full fl center ml20" style="width: 30%"> </el-card>
<el-image style="border-radius: 4%;width: 80%;height: 80%" </el-col>
:src="certSvg">
<div slot="placeholder" class="image-slot"> <el-col :xs="24" :sm="8" :md="8" :lg="8" v-hasPermi="['home:index:certWarn']">
加载中<span class="dot">...</span> <el-card class="data-card warning-card" shadow="hover" @click.native="linkPage('/remind/sup/certRemind')">
<div class="card-content">
<div class="card-icon">
<el-image class="icon-image" :src="certSvg"></el-image>
</div> </div>
</el-image> <div class="card-info">
</div> <div class="card-title">资质预警</div>
<div class="height-full fr center mr20" @click="linkPage('/remind/sup/certRemind')"> <div class="card-value warning-value">{{ certMsgCount }}</div>
<span class="header d-block"> </div>
资质预警 </div>
</span> </el-card>
<span class="d-block mt10" :style="{'font-size': '32px','font-weight': 'bolder',color:'#FF0000'}" </el-col>
> </el-row>
{{ certMsgCount }}
</span>
</div>
</el-row>
</el-card>
</div> </div>
<!-- 分割线 -->
<div class="m0 grid-container grid-container2" style="height: calc(40%);margin-top: 10px"> <!-- 待办事项和审核送货单 -->
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:todo']"> <div class="dashboard-tables">
<div slot="header" class="header"> <el-row :gutter="20">
<el-icon class="el-icon-s-management"/> <el-col :xs="24" :sm="24" :md="12" :lg="12" v-hasPermi="['home:index:todo']">
待办事项{{ `(${todoCount}条)` }} <el-card class="table-card" shadow="hover">
<div class="fr"> <div slot="header" class="card-header">
<el-button type="text" style="font-size: 15px;color: unset" @click="getSysMsgTodoList"> <div class="header-title">
<el-icon class="el-icon-refresh"/> <i class="el-icon-s-management header-icon"></i>
重新加载 <span>待办事项</span>
</el-button> <el-tag size="small" type="info" class="count-tag">{{ todoCount }}</el-tag>
<el-button type="text" style="font-size: 15px;color: unset" </div>
@click.stop=""> <div class="header-actions">
更多 <el-button type="text" class="action-button" @click="getSysMsgTodoList">
<el-icon class="el-icon-d-arrow-right"/> <i class="el-icon-refresh"></i> 刷新
</el-button> </el-button>
</div> <el-button type="text" class="action-button">
</div> 更多 <i class="el-icon-d-arrow-right"></i>
<el-table </el-button>
v-loading="msgLoading" </div>
:data="msgList" </div>
height="calc(100% - 45px)"
stripe <el-table
style=""> v-loading="msgLoading"
<el-table-column :data="msgList"
type="index" height="400"
label="序号" stripe
width="50"/> border
<el-table-column :header-cell-style="{background:'#f5f7fa', color:'#606266'}"
label="消息编码" style="width: 100%">
prop="code" <el-table-column type="index" label="序号" width="50" align="center"/>
width="120"/> <el-table-column label="消息编码" prop="code" width="120" show-overflow-tooltip/>
<el-table-column <el-table-column label="消息类型" prop="msgTypeName" width="120" show-overflow-tooltip/>
label="消息类型" <el-table-column label="消息内容" prop="msgContent" min-width="200" show-overflow-tooltip/>
prop="msgTypeName" <el-table-column label="处理状态" prop="dealStatusName" width="100" align="center">
width="120"/> <template slot-scope="scope">
<el-table-column <el-tag :type="scope.row.dealStatus === '0' ? 'warning' : 'success'" size="small">
label="消息内容" {{ scope.row.dealStatusName }}
prop="msgContent" </el-tag>
width="280"/> </template>
<el-table-column </el-table-column>
label="处理状态" <el-table-column label="创建时间" prop="createTime" width="140" show-overflow-tooltip/>
prop="dealStatusName" <el-table-column label="操作" width="80" fixed="right" align="center">
width="120"/> <template slot-scope="scope">
<el-table-column <el-button type="primary" size="mini" @click="linkPage('/system/msg/sysMsgTodo')"></el-button>
label="推送状态" </template>
prop="pushStatusName" </el-table-column>
width="120"/> </el-table>
<el-table-column </el-card>
label="仓库" </el-col>
prop="invName"
width="120"/> <el-col :xs="24" :sm="24" :md="12" :lg="12" v-hasPermi="['home:index:ioAudit']">
<el-table-column <el-card class="table-card" shadow="hover">
label="部门" <div slot="header" class="card-header">
prop="deptName" <div class="header-title">
width="120"/> <i class="el-icon-s-platform header-icon"></i>
<el-table-column <span>审核送货单</span>
label="创建时间" <el-tag size="small" type="info" class="count-tag">{{ orderTotal }}</el-tag>
prop="createTime" </div>
width="140"/> <div class="header-actions">
<el-table-column label="操作" width="80" fixed="right"> <el-button type="text" class="action-button" @click="getOrderList">
<template slot-scope="scope"> <i class="el-icon-refresh"></i> 刷新
<el-button </el-button>
type="text" <el-button type="text" class="action-button" @click="linkPage('/pur/auditDelivery')">
@click="linkPage('/system/msg/sysMsgTodo')" 更多 <i class="el-icon-d-arrow-right"></i>
>处理 </el-button>
</el-button> </div>
</template> </div>
</el-table-column>
</el-table> <el-table
</el-card> v-loading="orderLoading"
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:ioAudit']"> :data="orderList"
<div slot="header" class="header"> height="400"
<el-icon class="el-icon-s-platform"/> stripe
审核送货单{{ `(${orderTotal}条)` }} border
<div class="fr"> :header-cell-style="{background:'#f5f7fa', color:'#606266'}"
<el-button type="text" style="font-size: 15px;color: unset" @click="getOrderList"> style="width: 100%">
<el-icon class="el-icon-refresh"/> <el-table-column type="index" label="序号" width="50" align="center"/>
重新加载 <el-table-column label="送货单号" prop="billNo" width="180" show-overflow-tooltip/>
</el-button> <el-table-column label="单据类型" prop="billTypeName" width="120" show-overflow-tooltip/>
<el-button type="text" style="font-size: 15px;color: unset" <el-table-column label="送货单位" prop="fromName" min-width="180" show-overflow-tooltip/>
@click="linkPage('/pur/auditDelivery')">更多 <el-table-column label="创建时间" prop="createTime" width="140" show-overflow-tooltip/>
<el-icon class="el-icon-d-arrow-right"/> <el-table-column label="采购部门" prop="deptName" width="120" show-overflow-tooltip/>
</el-button> <el-table-column label="收货仓库" prop="invName" width="120" show-overflow-tooltip/>
</div> <el-table-column label="操作" width="80" fixed="right" align="center">
</div> <template slot-scope="scope">
<el-table <el-button type="primary" size="mini" @click="linkPage('/pur/auditDelivery')"></el-button>
v-loading="orderLoading" </template>
:data="orderList" </el-table-column>
height="calc(100% - 45px)" </el-table>
stripe> </el-card>
<el-table-column </el-col>
type="index" </el-row>
label="序号"
width="50"/>
<el-table-column label="送货单号" prop="billNo" width="180"/>
<el-table-column label="单据类型" prop="billTypeName" width="150"/>
<el-table-column label="送货单位" prop="fromName" width="220"/>
<el-table-column label="创建时间" prop="createTime" width="150"/>
<el-table-column label="核对时间" prop="checkTime" width="150"/>
<el-table-column label="采购部门" prop="deptName" width="120">
</el-table-column>
<el-table-column label="收货仓库" prop="invName" width="120">
</el-table-column>
<el-table-column label="核对人" prop="checkUserName" width="120">
</el-table-column>
<el-table-column label="来源单号" prop="corpOrderId" width="180"/>
<!-- <el-table-column label="来源" prop="fromType" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- <span>{{ fromTypeMap[scope.row.fromType] }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="审核状态" prop="status" width="100">-->
<!-- <template slot-scope="scope">-->
<!-- <el-tag :type="statusFilterType(scope.row.status)">{{-->
<!-- checkStatus[scope.row.status]-->
<!-- }}-->
<!-- </el-tag>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="备注" prop="remark" width="180"/>
<el-table-column label="操作" width="80" fixed="right">
<template slot-scope="scope">
<el-button
type="text"
@click="linkPage('/pur/auditDelivery')"
>处理
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div> </div>
</div> </div>
</template> </template>
@ -212,41 +151,36 @@
<script> <script>
import {getOrderList} from "../api/inout/order"; import {getOrderList} from "../api/inout/order";
import {sysMsgTodoPage} from "../api/system/sysMsgTodoApi"; import {sysMsgTodoPage} from "../api/system/sysMsgTodoApi";
import productSvg from "@/assets/svg/已对照产品.svg"
import invSvg from "@/assets/svg/库存预警.svg"
import certSvg from "@/assets/svg/资质预警.svg"
import {getInvRemindMsgList} from "../api/system/invRemindMsg";
import {getUdiInfos} from "../api/basic/udiRelevance"; import {getUdiInfos} from "../api/basic/udiRelevance";
import {getSupCertgetCount, getSupCertRemindMsgList} from "../api/purchase/supCertRedmindMsg"; import {getInvRemindMsgList} from "../api/system/invRemindMsg";
import {getSupCertgetCount} from "../api/purchase/supCertRedmindMsg";
import productSvg from "@/assets/images/dashboard/product.svg";
import invSvg from "@/assets/images/dashboard/inventory.svg";
import certSvg from "@/assets/images/dashboard/certificate.svg";
export default { export default {
name: "Index",
data() { data() {
return { return {
productSvg: productSvg,
invSvg: invSvg,
certSvg: certSvg,
productCount: 0, productCount: 0,
invMsgCount: 0, invMsgCount: 0,
certMsgCount: 0, certMsgCount: 0,
// ==================================================
msgLoading: false,
todoCount: 0, todoCount: 0,
msgList: [],
// =======================================================================
// ==================================================
orderLoading: false,
orderTotal: 0, orderTotal: 0,
msgList: [],
orderList: [], orderList: [],
// ======================================================================= msgLoading: false,
orderLoading: false,
productSvg,
invSvg,
certSvg
}; };
}, },
created() { created() {
this.getProductCount() this.getProductCount();
this.getInvMsgCount() this.getInvMsgCount();
this.getCertMsgCount() this.getCertMsgCount();
this.getSysMsgTodoList() this.getSysMsgTodoList();
this.getOrderList() this.getOrderList();
}, },
methods: { methods: {
getProductCount() { getProductCount() {
@ -283,191 +217,231 @@ export default {
}) })
}, },
linkPage(path) { linkPage(path) {
console.log(path) this.$router.push(path);
this.$router.push(path)
}, },
getSysMsgTodoList() { getSysMsgTodoList() {
this.msgLoading = true this.msgLoading = true;
let msgQuery = { sysMsgTodoPage({
page: 1, page: 1,
limit: 5 limit: 5,
} dealStatus: "0",
sysMsgTodoPage(msgQuery).then(res => {
this.msgLoading = false
if (res.code != 20000) {
this.$message.error(res.message())
return
}
this.msgList = res.data.list || []
this.todoCount = res.data.total || 0
}).catch(e => {
this.$message.error(e.message)
this.msgLoading = false
this.msgList = []
this.todoCount = 0
}) })
.then((response) => {
this.msgLoading = false;
if (response.code === 20000) {
this.msgList = response.rows;
this.todoCount = response.total;
} else {
this.$message.error(response.msg);
}
})
.catch(() => {
this.msgLoading = false;
});
}, },
getOrderList() { getOrderList() {
this.orderLoading = true this.orderLoading = true;
let orderQuery = { getOrderList({
page: 1, page: 1,
limit: 5, limit: 5,
status: 10, status: "0",
vueType: "supDelivery", })
} .then((response) => {
getOrderList(orderQuery)
.then((res) => {
this.orderLoading = false; this.orderLoading = false;
if (res.code === 20000) { if (response.code === 20000) {
this.orderList = res.data.list || []; this.orderList = response.rows;
this.orderTotal = res.data.total || 0; this.orderTotal = response.total;
} else { } else {
this.$message.error(res.message); this.$message.error(response.msg);
} }
}) })
.catch((error) => { .catch(() => {
this.$message.error(error.message)
this.orderLoading = false; this.orderLoading = false;
this.orderList = [];
this.orderTotal = 0;
}); });
}, },
}, },
}; };
</script> </script>
<style scoped lang="scss"> <style lang="scss" scoped>
.center { @import "../assets/styles/variables.scss";
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.el-row .el-card {
margin: 0;
.el-card__body { .home {
padding: 0 !important;
}
}
.grid-item {
height: 100%; height: 100%;
padding: 15px; padding: 20px;
overflow-y: auto;
.el-row, .el-col { background-color: #f5f7fa;
height: 100%;
} //
.welcome-section {
.header { margin-bottom: 24px;
color: #676a6c;
font-size: 20px; .welcome-title {
font-weight: bolder; font-size: 24px;
font-weight: 600;
color: #303133;
margin: 0;
padding: 0;
}
.welcome-divider {
margin-top: 16px;
margin-bottom: 0;
}
} }
.el-table { //
margin-top: 10px; .dashboard-cards {
width: 100%; margin-bottom: 24px;
.data-card {
height: 120px;
border-radius: $base-border-radius;
transition: all 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
}
.card-content {
display: flex;
align-items: center;
height: 100%;
}
.card-icon {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
margin-left: 20px;
.icon-image {
width: 60px;
height: 60px;
transition: all 0.3s;
}
}
.card-info {
flex: 1;
padding: 0 20px;
.card-title {
font-size: 16px;
color: #606266;
margin-bottom: 10px;
}
.card-value {
font-size: 28px;
font-weight: bold;
color: $blue;
}
.warning-value {
color: #f56c6c;
}
}
}
.warning-card {
cursor: pointer;
&:hover .icon-image {
transform: scale(1.1);
}
}
} }
}
//
.grid-container { .dashboard-tables {
height: inherit; .table-card {
display: grid; margin-bottom: 24px;
grid-gap: 10px; border-radius: $base-border-radius;
.el-card { .card-header {
margin: 0; display: flex;
justify-content: space-between;
align-items: center;
padding: 0;
.header-title {
display: flex;
align-items: center;
.header-icon {
font-size: 18px;
margin-right: 8px;
color: $blue;
}
span {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.count-tag {
margin-left: 8px;
}
}
.header-actions {
.action-button {
font-size: 14px;
color: #606266;
&:hover {
color: $blue;
}
i {
margin-right: 4px;
}
}
}
}
.el-table {
margin-top: 16px;
::v-deep .el-table__header th {
background-color: #f5f7fa;
color: #606266;
font-weight: 600;
}
::v-deep .el-table__row {
transition: all 0.3s;
&:hover {
background-color: rgba($blue, 0.06);
}
}
}
}
} }
} }
.grid-container1 { //
grid-template-columns: repeat(1, 1fr); @media (max-width: 768px) {
.home {
} padding: 15px;
.grid-container2 { .dashboard-cards {
grid-template-columns: repeat(2, 1fr); .data-card {
margin-bottom: 15px;
} }
.grid-container3 {
grid-template-columns: repeat(3, 1fr);
}
.grid-container4 {
grid-template-columns: repeat(4, 1fr);
}
.home {
blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
border-left: 5px solid #eee;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.col-item {
margin-bottom: 20px;
}
ul {
padding: 0;
margin: 0;
}
height: calc(100%);
font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
color: #676a6c;
overflow-x: hidden;
ul {
list-style-type: none;
}
h4 {
margin-top: 0px;
}
h2 {
margin-top: 10px;
font-size: 26px;
color: #000610;
font-weight: bolder;
}
p {
margin-top: 10px;
b {
font-weight: 700;
} }
}
.dashboard-tables {
.update-log { .table-card {
ol { margin-bottom: 15px;
display: block; }
list-style-type: decimal;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0;
margin-inline-end: 0;
padding-inline-start: 40px;
} }
} }
} }
</style> </style>

@ -1,66 +1,77 @@
<template> <template>
<div> <div>
<el-card class="el-card"> <el-card class="list-card">
<el-form :model="filterQuery" class="query-form" size="mini" label-width="100px" v-show="showSearch"> <div slot="header">
<el-row> <span>库存管理</span>
<el-col :span="20"> <el-button
<el-form-item class="query-form-item" label-width="100px" label="UDI码:"> type="text"
icon="el-icon-view"
@click="hideSearch"
>{{ showSearch ? '隐藏搜索' : '显示搜索' }}</el-button>
</div>
<el-form
v-show="showSearch"
:model="filterQuery"
class="search-form"
label-width="100px"
>
<el-row :gutter="16">
<el-col :xs="24" :sm="24" :md="24" :lg="24">
<el-form-item label="UDI码:">
<el-input <el-input
id="inputer" id="inputer"
v-model="filterQuery.udiCode" v-model="filterQuery.udiCode"
placeholder="UDI码" placeholder="请输入UDI码"
ref='inputRef' ref='inputRef'
@keypress.enter.native="enterKey($event)" @keypress.enter.native="enterKey($event)"
clearable clearable
prefix-icon="el-icon-search"
></el-input> ></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row :gutter="16">
<el-col :span="6"> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item class="query-form-item" label="所属仓库:"> <el-form-item label="所属仓库:">
<el-select v-model="filterQuery.invCode" placeholder="请选择所属仓库" clearable="true" <el-select
style="width: 90%" v-model="filterQuery.invCode"
placeholder="请选择所属仓库"
clearable
style="width: 100%"
> >
<el-option <el-option
v-for="item in invList" v-for="item in invList"
:key="item.name" :key="item.name"
:label="item.name" :label="item.name"
:value="item.code"> :value="item.code">
<span style="float: left">{{ item.name }}</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item class="query-form-item" label="货位:"> <el-form-item label="货位:">
<el-input v-model="filterQuery.nameCode" placeholder="货位" <el-input
style="width: 90%" v-model="filterQuery.nameCode"
clearable="true"></el-input> placeholder="请输入货位"
clearable
prefix-icon="el-icon-location"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col :span="6">--> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<!-- <el-form-item class="query-form-item" label="产品标识DI:">--> <el-form-item label="供应商名称:">
<!-- <el-input v-model="filterQuery.nameCode" placeholder="产品标识DI"-->
<!-- style="width: 90%"-->
<!-- clearable="true"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="6">
<el-form-item class="query-form-item" label="供应商名称:">
<el-select <el-select
v-model="filterQuery.supId" v-model="filterQuery.supId"
filterable filterable
remote remote
clearable="true" clearable
reserve-keyword reserve-keyword
placeholder="供应商名称" placeholder="请输入供应商名称"
:remote-method="findMethod" :remote-method="findMethod"
size="mini"
:loading="corpLoading" :loading="corpLoading"
@change="corpChange" @change="corpChange"
style="width: 90%" style="width: 100%"
> >
<el-option <el-option
v-for="item in fromOptions" v-for="item in fromOptions"
@ -68,127 +79,145 @@
:label="item.name" :label="item.name"
:value="item.erpId" :value="item.erpId"
> >
<span style="float: left">{{ item.name }}</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="生产企业:">
<el-col :span="6"> <el-input
<el-form-item class="query-form-item" label="生产企业:"> v-model="filterQuery.ylqxzcrbarmc"
<el-input v-model="filterQuery.ylqxzcrbarmc" placeholder="生产企业" placeholder="请输入生产企业"
style="width: 90%" clearable
clearable="true"></el-input> prefix-icon="el-icon-office-building"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="16">
<el-row> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-col :span="6"> <el-form-item label="注册/备案号:">
<el-form-item class="query-form-item" label="注册/备案号:"> <el-input
<el-input v-model="filterQuery.zczbhhzbapzbh" placeholder="注册/备案号" v-model="filterQuery.zczbhhzbapzbh"
style="width: 90%" placeholder="请输入注册/备案号"
clearable="true"></el-input> clearable
prefix-icon="el-icon-document"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item class="query-form-item" label="物资名称:"> <el-form-item label="物资名称:">
<el-input v-model="filterQuery.cpmctymc" placeholder="物资名称" <el-input
style="width: 90%" v-model="filterQuery.cpmctymc"
clearable="true"></el-input> placeholder="请输入物资名称"
clearable
prefix-icon="el-icon-goods"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item class="query-form-item" label="规格型号:"> <el-form-item label="规格型号:">
<el-input v-model="filterQuery.ggxh" placeholder="规格型号" <el-input
style="width: 90%" v-model="filterQuery.ggxh"
clearable="true"></el-input> placeholder="请输入规格型号"
clearable
prefix-icon="el-icon-tickets"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item class="query-form-item" label="批次号:"> <el-form-item label="批次号:">
<el-input v-model="filterQuery.batchNo" placeholder="批次号" <el-input
style="width: 90%" v-model="filterQuery.batchNo"
clearable="true"></el-input> placeholder="请输入批次号"
clearable
prefix-icon="el-icon-collection-tag"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<div class="top-right-btn">
<el-button-group> <div class="action-group">
<el-button icon="el-icon-view" type="primary" @click="hideSearch">/</el-button> <div class="left-actions">
<el-button <el-button
type="primary" type="primary"
icon="el-icon-refresh" icon="el-icon-refresh"
@click="onReset" @click="onReset"
>重置 >重置</el-button>
</el-button> <el-button
<el-button type="primary" icon="el-icon-search" @click="onSubmit" type="primary"
>查询 icon="el-icon-search"
</el-button @click="onSubmit"
> >查询</el-button>
</el-button-group> </div>
</div> </div>
<el-divider style="margin: 15px"></el-divider>
<el-table v-loading="loading" :data="list" style="width: 100%" highlight-current-row
border>
<el-table-column label="序号" type="index"></el-table-column>
<el-table-column label="仓库" prop="invName" v-if="showSup"
show-overflow-tooltip width="200"></el-table-column>
<el-table-column label="货位" prop="spaceName" v-if="showSup"
show-overflow-tooltip width="200"></el-table-column>
<el-table-column label="DI标识" prop="nameCode" width="140"></el-table-column>
<el-table-column label="物资名称" prop="cpmctymc" width="200"></el-table-column>
<el-table-column label="规格型号" prop="ggxh" show-overflow-tooltip></el-table-column>
<el-table-column label="批次号" prop="batchNo" width="120"></el-table-column>
<el-table-column label="价格" prop="price" width="120"></el-table-column>
<!-- <el-table-column label="生产日期" prop="productionDate" width="120"></el-table-column>-->
<!-- <el-table-column label="失效日期" prop="expireDate" width="120"></el-table-column>-->
<!-- <el-table-column label="入库数量" prop="inCount" width="120"></el-table-column>-->
<!-- <el-table-column label="出库数量" prop="outCount" width="120"></el-table-column>-->
<el-table-column label="库存数量" prop="reCount" width="120"></el-table-column>
<el-table-column label="生产企业" prop="ylqxzcrbarmc" v-if="showSup" show-overflow-tooltip
width="180"></el-table-column>
<el-table-column label="注册/备案号" prop="zczbhhzbapzbh" v-if="showSup" show-overflow-tooltip <el-table
width="200"></el-table-column> v-loading="loading"
<el-table-column label="供应商" prop="supName" v-if="showSup" show-overflow-tooltip :data="list"
width="200"></el-table-column> stripe
<!-- <el-table-column label="部门" prop="deptName" v-if="showSup"--> class="list-table"
<!-- show-overflow-tooltip width="120"></el-table-column>--> highlight-current-row
<el-table-column label="操作" width="200" fixed="right"> border
>
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
<el-table-column label="仓库" prop="invName" v-if="showSup" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="货位" prop="spaceName" v-if="showSup" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="DI标识" prop="nameCode" min-width="140" show-overflow-tooltip></el-table-column>
<el-table-column label="物资名称" prop="cpmctymc" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="规格型号" prop="ggxh" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="批次号" prop="batchNo" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="价格" prop="price" width="100" align="right">
<template slot-scope="scope">
<span>{{ scope.row.price ? '¥' + scope.row.price : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="库存数量" prop="reCount" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.reCount > 10 ? 'success' : 'danger'">{{ scope.row.reCount }}</el-tag>
</template>
</el-table-column>
<el-table-column label="生产企业" prop="ylqxzcrbarmc" v-if="showSup" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="注册/备案号" prop="zczbhhzbapzbh" v-if="showSup" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="供应商" prop="supName" v-if="showSup" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="180" align="center" class-name="operation-column" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
type="text" type="primary"
size="small" size="mini"
icon="el-icon-bell"
@click.native.stop="invRemindSet(scope.row)" @click.native.stop="invRemindSet(scope.row)"
>添加预警设置 circle
</el-button title="添加预警设置"
> ></el-button>
<el-button <el-button
type="text" type="success"
size="small" size="mini"
icon="el-icon-view"
@click.native.stop="detailDialog(scope.row)" @click.native.stop="detailDialog(scope.row)"
>详情 circle
</el-button title="查看详情"
> ></el-button>
<el-button <el-button
type="text" type="danger"
size="small" size="mini"
icon="el-icon-delete"
@click.native.stop="deleteDialog(scope.row.id)" @click.native.stop="deleteDialog(scope.row.id)"
>删除 circle
</el-button title="删除"
> ></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="total>0" v-show="total>0"
:total="total" :total="total"
:limit.sync="filterQuery.limit" :limit.sync="filterQuery.limit"
:page.sync="filterQuery.page" :page.sync="filterQuery.page"
@pagination="getList" @pagination="getList"
class="pagination-container"
></pagination> ></pagination>
</el-card> </el-card>
@ -199,27 +228,28 @@
:close-on-press-escape="false" :close-on-press-escape="false"
width="85%" width="85%"
v-if="detailDialogVisible" v-if="detailDialogVisible"
class="form-dialog"
> >
<invProductsDetail <invProductsDetail
:inputQuery="inputQuery" :closeDialog="closeDetailDialog"
v-on:closeDetailDialog="closeDetailDialog" :row="detailRow"
></invProductsDetail> ></invProductsDetail>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
title="添加库存预警设置" title="库存预警设置"
:visible.sync="addInvRemindSetDialogVisible" :visible.sync="remindSetDialogVisible"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
width="60%" width="50%"
v-if="addInvRemindSetDialogVisible" v-if="remindSetDialogVisible"
class="form-dialog"
> >
<addInvRemindSetDialog <addInvRemindSetDialog
:invId="invId"
:closeDialog="closeRemindSetDialog" :closeDialog="closeRemindSetDialog"
:row="detailRow"
></addInvRemindSetDialog> ></addInvRemindSetDialog>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -232,69 +262,64 @@ import invProductsDetail from "@/views/inventory/InvProductsDetail.vue";
import addInvRemindSetDialog from "@/views/inventory/addInvRemindSetDialog.vue"; import addInvRemindSetDialog from "@/views/inventory/addInvRemindSetDialog.vue";
export default { export default {
name: "InvProducts", name: "ModernInvProducts",
components: {
invProductsDetail,
addInvRemindSetDialog
},
data() { data() {
return { return {
showSearch: true, showSearch: true,
showSup: true,
filterQuery: { filterQuery: {
udiCode: null, invCode: "",
nameCode: null, nameCode: "",
cpmctymc: null, cpmctymc: "",
ggxh: null, ggxh: "",
batchNo: null, batchNo: "",
supId: null, udiCode: "",
zczbhhzbapzbh: null, zczbhhzbapzbh: "",
ylqxzcrbarmc: null, ylqxzcrbarmc: "",
invCode: this.$store.getters.locInvCode, supId: "",
page: 1, page: 1,
limit: 10, limit: 10
}, },
list: [],
total: 0,
invList: [], invList: [],
loading: false,
deleteData: {
id: "",
status: 10,
},
corpLoading: false,
dialogVisible: false,
fromOptions: [], fromOptions: [],
showSup: true, corpLoading: false,
total: 0,
list: [],
loading: false,
detailDialogVisible: false, detailDialogVisible: false,
inputQuery: { remindSetDialogVisible: false,
cpmctymc: null, detailRow: null
nameCode: null,
batchNo: null,
ggxh: null,
productionDate: null,
expireDate: null,
supId: null,
deptCode: null,
invCode: null,
price:null,
},
addInvRemindSetDialogVisible: null,
invId: null
}; };
}, },
created() {
this.getInvList();
this.getList();
},
mounted() {
this.$nextTick(() => {
if (this.$refs.inputRef) {
this.$refs.inputRef.focus();
}
});
},
methods: { methods: {
onReset() { onReset() {
this.$router.push({
path: "",
});
this.filterQuery = { this.filterQuery = {
udiCode: null, invCode: "",
nameCode: null, nameCode: "",
cpmctymc: null, cpmctymc: "",
ggxh: null, ggxh: "",
batchNo: null, batchNo: "",
supId: null, udiCode: "",
zczbhhzbapzbh: null, zczbhhzbapzbh: "",
ylqxzcrbarmc: null, ylqxzcrbarmc: "",
invCode: this.$store.getters.locInvCode, supId: "",
page: 1, page: 1,
limit: 10, limit: 10
}; };
this.getList(); this.getList();
}, },
@ -305,135 +330,100 @@ export default {
hideSearch() { hideSearch() {
this.showSearch = !this.showSearch; this.showSearch = !this.showSearch;
}, },
handleSizeChange(val) { enterKey(e) {
this.filterQuery.limit = val; this.onSubmit();
this.getList();
},
handleCurrentChange(val) {
this.filterQuery.page = val;
this.getList();
}, },
getList() { getList() {
this.loading = true; this.loading = true;
getProduct(this.filterQuery).then((res) => { getInvProduct(this.filterQuery).then(response => {
this.loading = false; this.loading = false;
if (res.code === 20000) { if (response.code === 20000) {
this.list = res.data.list || []; this.list = response.data.list;
this.total = res.data.total || 0; this.total = response.data.total;
} else { } else {
this.$message.error(res.message); this.$message.error(response.msg);
this.list = [];
this.total = 0;
} }
}).catch((error) => { }).catch(() => {
this.loading = false; this.loading = false;
this.$message.error(error.message); });
this.list = [];
this.total = 0;
})
}, },
getInvList() { getInvList() {
let query = { getInvListByUser().then(response => {
advanceType: false, if (response.code === 20000) {
}; this.invList = response.data;
getInvListByUser(query) } else {
.then((response) => { this.$message.error(response.msg);
this.invList = response.data || []; }
this.getList(); });
})
.catch(() => {
});
}, },
findMethod(key) { findMethod(key) {
this.corpLoading = true; if (key) {
this.fromOptions = []; this.corpLoading = true;
let params = { getCorpList({
key: key, name: key,
corpType: 2, page: 1,
page: 1, limit: 20
limit: 20 }).then(response => {
}; this.corpLoading = false;
getBasicUnitMaintains(params).then((res) => { if (response.code === 20000) {
this.corpLoading = false; this.fromOptions = response.data.list;
this.fromOptions = res.data.list || []; } else {
}).catch(() => { this.$message.error(response.msg);
this.corpLoading = false; }
}) }).catch(() => {
this.corpLoading = false;
});
} else {
this.fromOptions = [];
}
}, },
corpChange(value) { corpChange(value) {
if (!isBlank(value)) { this.filterQuery.supId = value;
this.findMethod(value);
}
}, },
detailDialog(row) { detailDialog(row) {
this.detailRow = row;
this.detailDialogVisible = true; this.detailDialogVisible = true;
this.inputQuery = {
relId: row.relIdFk,
cpmctymc: row.cpmctymc,
nameCode: row.nameCode,
batchNo: row.batchNo,
ggxh: row.ggxh,
productionDate: row.productionDate,
expireDate: row.expireDate,
supId: row.supId,
deptCode: row.deptCode,
invCode: row.invCode,
price: row.price
}
}, },
closeDetailDialog() { closeDetailDialog() {
this.detailDialogVisible = false; this.detailDialogVisible = false;
this.detailRow = null;
}, },
deleteDialog(id) { deleteDialog(id) {
this.$confirm("此操作将永久删除此库存信息,是否继续?", "提示", { this.$confirm('是否确认删除该条库存记录?', "警告", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(() => { }).then(() => {
this.deleteInvProduct(id); deleteInvProduct(id).then(response => {
}).catch(() => { if (response.code === 20000) {
}); this.$message.success("删除成功");
}, this.getList();
deleteInvProduct(id) { } else {
let params = {id: id}; this.$message.error(response.msg);
deleteInvProduct(params).then((res) => { }
if (res.code === 20000) { });
this.$message.success("删除成功!");
this.getList();
} else {
this.$message.error(res.message);
}
}).catch((error) => {
this.$message.error(error.message);
}); });
}, },
invRemindSet(row) { invRemindSet(row) {
this.invId = row.id; this.detailRow = row;
this.addInvRemindSetDialogVisible = true; this.remindSetDialogVisible = true;
}, },
closeRemindSetDialog() { closeRemindSetDialog() {
this.invId = null; this.remindSetDialogVisible = false;
this.addInvRemindSetDialogVisible = false; this.detailRow = null;
}, }
}, }
components: {
invProductsDetail,
addInvRemindSetDialog
},
mounted() {
document.body.ondrop = function (event) {
event.preventDefault();
event.stopPropagation();
};
},
created() {
this.findMethod();
this.getInvList();
this.getList();
},
}; };
</script> </script>
<style type="text/scss" lang="scss"> <style lang="scss" scoped>
</style> .el-card {
margin-bottom: 20px;
}
.form-dialog {
.el-dialog__body {
padding: 20px;
}
}
</style>

@ -0,0 +1,428 @@
<template>
<div>
<el-card class="list-card">
<div slot="header">
<span>库存管理</span>
<el-button
type="text"
icon="el-icon-view"
@click="hideSearch"
>{{ showSearch ? '隐藏搜索' : '显示搜索' }}</el-button>
</div>
<el-form
v-show="showSearch"
:model="filterQuery"
class="search-form"
label-width="100px"
>
<el-row :gutter="16">
<el-col :xs="24" :sm="24" :md="24" :lg="24">
<el-form-item label="UDI码:">
<el-input
id="inputer"
v-model="filterQuery.udiCode"
placeholder="请输入UDI码"
ref='inputRef'
@keypress.enter.native="enterKey($event)"
clearable
prefix-icon="el-icon-search"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="所属仓库:">
<el-select
v-model="filterQuery.invCode"
placeholder="请选择所属仓库"
clearable
style="width: 100%"
>
<el-option
v-for="item in invList"
:key="item.name"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="货位:">
<el-input
v-model="filterQuery.nameCode"
placeholder="请输入货位"
clearable
prefix-icon="el-icon-location"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="供应商名称:">
<el-select
v-model="filterQuery.supId"
filterable
remote
clearable
reserve-keyword
placeholder="请输入供应商名称"
:remote-method="findMethod"
:loading="corpLoading"
@change="corpChange"
style="width: 100%"
>
<el-option
v-for="item in fromOptions"
:key="item.name"
:label="item.name"
:value="item.erpId"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="生产企业:">
<el-input
v-model="filterQuery.ylqxzcrbarmc"
placeholder="请输入生产企业"
clearable
prefix-icon="el-icon-office-building"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="注册/备案号:">
<el-input
v-model="filterQuery.zczbhhzbapzbh"
placeholder="请输入注册/备案号"
clearable
prefix-icon="el-icon-document"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="物资名称:">
<el-input
v-model="filterQuery.cpmctymc"
placeholder="请输入物资名称"
clearable
prefix-icon="el-icon-goods"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="规格型号:">
<el-input
v-model="filterQuery.ggxh"
placeholder="请输入规格型号"
clearable
prefix-icon="el-icon-tickets"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="批次号:">
<el-input
v-model="filterQuery.batchNo"
placeholder="请输入批次号"
clearable
prefix-icon="el-icon-collection-tag"
></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="action-group">
<div class="left-actions">
<el-button
type="primary"
icon="el-icon-refresh"
@click="onReset"
>重置</el-button>
<el-button
type="primary"
icon="el-icon-search"
@click="onSubmit"
>查询</el-button>
</div>
</div>
<el-table
v-loading="loading"
:data="list"
class="list-table"
highlight-current-row
border
>
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
<el-table-column label="仓库" prop="invName" v-if="showSup" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="货位" prop="spaceName" v-if="showSup" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="DI标识" prop="nameCode" min-width="140" show-overflow-tooltip></el-table-column>
<el-table-column label="物资名称" prop="cpmctymc" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="规格型号" prop="ggxh" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="批次号" prop="batchNo" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="价格" prop="price" width="100" align="right">
<template slot-scope="scope">
<span>{{ scope.row.price ? '¥' + scope.row.price : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="库存数量" prop="reCount" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.reCount > 10 ? 'success' : 'danger'">{{ scope.row.reCount }}</el-tag>
</template>
</el-table-column>
<el-table-column label="生产企业" prop="ylqxzcrbarmc" v-if="showSup" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="注册/备案号" prop="zczbhhzbapzbh" v-if="showSup" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="供应商" prop="supName" v-if="showSup" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="180" align="center" class-name="operation-column" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-bell"
@click.native.stop="invRemindSet(scope.row)"
circle
title="添加预警设置"
></el-button>
<el-button
type="success"
size="mini"
icon="el-icon-view"
@click.native.stop="detailDialog(scope.row)"
circle
title="查看详情"
></el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.native.stop="deleteDialog(scope.row.id)"
circle
title="删除"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:limit.sync="filterQuery.limit"
:page.sync="filterQuery.page"
@pagination="getList"
class="pagination-container"
></pagination>
</el-card>
<el-dialog
title="库存详情"
:visible.sync="detailDialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
width="85%"
v-if="detailDialogVisible"
class="form-dialog"
>
<invProductsDetail
:closeDialog="closeDetailDialog"
:row="detailRow"
></invProductsDetail>
</el-dialog>
<el-dialog
title="库存预警设置"
:visible.sync="remindSetDialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
width="50%"
v-if="remindSetDialogVisible"
class="form-dialog"
>
<addInvRemindSetDialog
:closeDialog="closeRemindSetDialog"
:row="detailRow"
></addInvRemindSetDialog>
</el-dialog>
</div>
</template>
<script>
import {getInvListByUser} from "@/api/system/invWarehouse";
import {getInvProduct, deleteInvProduct, getProduct} from "@/api/inventory/invPorduct";
import {getBasicUnitMaintains} from "@/api/basic/basicUnitMaintain";
import {isBlank} from "@/utils/strUtil";
import invProductsDetail from "@/views/inventory/InvProductsDetail.vue";
import addInvRemindSetDialog from "@/views/inventory/addInvRemindSetDialog.vue";
export default {
name: "ModernInvProducts",
components: {
invProductsDetail,
addInvRemindSetDialog
},
data() {
return {
showSearch: true,
showSup: true,
filterQuery: {
invCode: "",
nameCode: "",
cpmctymc: "",
ggxh: "",
batchNo: "",
udiCode: "",
zczbhhzbapzbh: "",
ylqxzcrbarmc: "",
supId: "",
page: 1,
limit: 10
},
invList: [],
fromOptions: [],
corpLoading: false,
total: 0,
list: [],
loading: false,
detailDialogVisible: false,
remindSetDialogVisible: false,
detailRow: null
};
},
created() {
this.getInvList();
this.getList();
},
mounted() {
this.$nextTick(() => {
if (this.$refs.inputRef) {
this.$refs.inputRef.focus();
}
});
},
methods: {
onReset() {
this.filterQuery = {
invCode: "",
nameCode: "",
cpmctymc: "",
ggxh: "",
batchNo: "",
udiCode: "",
zczbhhzbapzbh: "",
ylqxzcrbarmc: "",
supId: "",
page: 1,
limit: 10
};
this.getList();
},
onSubmit() {
this.filterQuery.page = 1;
this.getList();
},
hideSearch() {
this.showSearch = !this.showSearch;
},
enterKey(e) {
this.onSubmit();
},
getList() {
this.loading = true;
getInvProduct(this.filterQuery).then(response => {
this.loading = false;
if (response.code === 20000) {
this.list = response.data.list;
this.total = response.data.total;
} else {
this.$message.error(response.msg);
}
}).catch(() => {
this.loading = false;
});
},
getInvList() {
getInvListByUser().then(response => {
if (response.code === 20000) {
this.invList = response.data;
} else {
this.$message.error(response.msg);
}
});
},
findMethod(key) {
if (key) {
this.corpLoading = true;
getCorpList({
name: key,
page: 1,
limit: 20
}).then(response => {
this.corpLoading = false;
if (response.code === 20000) {
this.fromOptions = response.data.list;
} else {
this.$message.error(response.msg);
}
}).catch(() => {
this.corpLoading = false;
});
} else {
this.fromOptions = [];
}
},
corpChange(value) {
this.filterQuery.supId = value;
},
detailDialog(row) {
this.detailRow = row;
this.detailDialogVisible = true;
},
closeDetailDialog() {
this.detailDialogVisible = false;
this.detailRow = null;
},
deleteDialog(id) {
this.$confirm('是否确认删除该条库存记录?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
deleteInvProduct(id).then(response => {
if (response.code === 20000) {
this.$message.success("删除成功");
this.getList();
} else {
this.$message.error(response.msg);
}
});
});
},
invRemindSet(row) {
this.detailRow = row;
this.remindSetDialogVisible = true;
},
closeRemindSetDialog() {
this.remindSetDialogVisible = false;
this.detailRow = null;
}
}
};
</script>
<style lang="scss" scoped>
.el-card {
margin-bottom: 20px;
}
.form-dialog {
.el-dialog__body {
padding: 20px;
}
}
</style>

@ -1,143 +1,118 @@
<template> <template>
<div class="login-container"> <div class="login-container">
<div> <div class="login-background">
<el-row> <div class="login-left">
<!-- <h3 class="toptitle">漳州市中医院</h3>--> <div class="login-title-container">
<h1 class="main-title">{{ title }}</h1>
<h3 class="toptitle">{{ title }}</h3> <h2 class="sub-title">{{ subTitle }}</h2>
</el-row> <p class="description">高效安全的进销存管理系统</p>
<el-row>
<h3 class="topSubtitle">{{ subTitle }}</h3>
</el-row>
</div>
<el-form
@submit.native.prevent
class="card-box login-form"
autocomplete="on"
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-position="left"
>
<el-card class="box-card">
<div style="text-align: center; margin-top: 10px; margin-bottom: 15px">
<img alt="element-logo" src="@/assets/logo/logoDm.png"/>
</div> </div>
<h3 class="title">用户登录</h3> </div>
<el-form-item prop="username" class="item" style="margin-top: -20px">
<el-input <div class="login-right">
prefix-icon="el-icon-user" <div class="login-form-container">
placeholder="账号" <div class="login-logo">
name="username" <img alt="logo" src="@/assets/logo/logoDm.png"/>
autocomplete="on" </div>
v-model="loginForm.username"
> <h2 class="welcome-text">欢迎登录</h2>
<i slot="prefix" class="el-input__icon">
<icon-svg icon-class="user"/> <el-form
</i> @submit.native.prevent
</el-input> class="login-form"
</el-form-item>
<el-form-item prop="password" class="item">
<el-input
prefix-icon="el-icon-s-goods"
placeholder="密码"
name="password"
:type="isShowPwd ? 'text' : 'password'"
@keyup.enter.native="handleLogin"
v-model="loginForm.password"
autocomplete="on" autocomplete="on"
:model="loginForm"
:rules="rules"
ref="loginForm"
label-position="top"
> >
<i slot="prefix" class="el-input__icon"> <el-form-item prop="username">
<icon-svg icon-class="pwd"/> <el-input
</i> prefix-icon="el-icon-user"
<i placeholder="请输入账号"
slot="suffix" name="username"
class="el-input__icon" autocomplete="on"
@click="isShowPwd = !isShowPwd" v-model="loginForm.username"
> >
<icon-svg icon-class="eye"/> </el-input>
</i> </el-form-item>
</el-input>
</el-form-item> <el-form-item prop="password">
<el-form-item <el-input
prop="verificationCode" prefix-icon="el-icon-lock"
class="item" placeholder="请输入密码"
style="background-color: white" name="password"
> :type="isShowPwd ? 'text' : 'password'"
<Verify @keyup.enter.native="handleLogin"
ref="checkV" v-model="loginForm.password"
:showButton="false" autocomplete="on"
:barSize="{ width: '305px', height: '37px' }" >
:vOffset="5" <i
@success="verifyAlert('success')" slot="suffix"
@error="verifyAlert('error')" class="el-input__icon password-toggle"
:type="3" @click="isShowPwd = !isShowPwd"
></Verify> >
</el-form-item> <i :class="isShowPwd ? 'el-icon-view' : 'el-icon-hide'"></i>
<div style="text-align: center; margin-top: 15px"> </i>
<el-button </el-input>
type="primary" </el-form-item>
style="width: 60%; margin-bottom: 30px"
:loading="loading" <el-form-item prop="verificationCode" class="verify-container">
@click.native="handleLogin()" <Verify
>登录 ref="checkV"
</el-button> :showButton="false"
</div> :barSize="{ width: '100%', height: '40px' }"
<div style="margin-top: -15px"> :vOffset="5"
<a style="margin-left: 50%; font-size: 12px" :href="'#/register'" @success="verifyAlert('success')"
>新用户注册</a @error="verifyAlert('error')"
> :type="3"
<a style="margin-left: 5%; font-size: 12px" :href="'#/forgetPasswd'" ></Verify>
>忘记密码</a </el-form-item>
>
<el-form-item>
<el-button
type="primary"
class="login-button"
:loading="loading"
@click.native="handleLogin()"
>登录</el-button>
</el-form-item>
<div class="login-options">
<router-link to="/register" class="text-link">新用户注册</router-link>
<router-link to="/forgetPasswd" class="text-link">忘记密码</router-link>
</div>
</el-form>
</div> </div>
</el-card> </div>
</el-form> </div>
<el-dialog title="修改密码" :visible.sync="passwordFormVisible" width="85%" top="5vh" <!-- 修改密码对话框 -->
:close-on-click-modal="false" <el-dialog
:show-close="false" title="修改密码"
:close-on-press-escape="false"> :visible.sync="passwordFormVisible"
<el-form :model="passwordFormData" :rules="passwordFormDataRules" ref="passwordFormData"> width="400px"
<el-form-item label="原始密码" prop="old_password"> top="15vh"
<el-input type="password" v-model="passwordFormData.oldPassword" auto-complete="off"></el-input> :close-on-click-modal="false"
:show-close="false"
:close-on-press-escape="false"
class="password-dialog"
>
<el-form :model="passwordFormData" :rules="passwordFormDataRules" ref="passwordFormData" label-width="100px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="passwordFormData.oldPassword" type="password" placeholder="请输入旧密码" show-password></el-input>
</el-form-item> </el-form-item>
<el-form-item label="新密码" prop="new_password"> <el-form-item label="新密码" prop="newPassword">
<el-input type="password" v-model="passwordFormData.newPassword" auto-complete="off"></el-input> <el-input v-model="passwordFormData.newPassword" type="password" placeholder="请输入新密码" show-password></el-input>
</el-form-item> </el-form-item>
<el-form-item label="确认密码" prop="confirmPassword"> <el-form-item label="确认密码" prop="confirmPassword">
<el-input type="password" v-model="passwordFormData.confirmPassword" auto-complete="off"></el-input> <el-input v-model="passwordFormData.confirmPassword" type="password" placeholder="请确认新密码" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="passwdSubmit" class="dialog-button">确认</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer">
<!-- <el-button @click.native="passwordFormVisible = !passwordFormVisible">取消</el-button> -->
<el-button type="primary" @click.native="passwdSubmit()" :loading="passwordLoading">提交
</el-button>
</div>
</el-dialog> </el-dialog>
<div
style="
position: absolute;
bottom: 0;
font-size: 12px;
color: white;
width: 100%;
display: flex;
justify-content: center;
"
>
<a href="http://www.xmglxp.com/" target="_blank">
软件名称: 供应商自助管理平台
</a>
<a
href="http://www.xmglxp.com/"
target="_blank"
style="margin-left: 20px; font-size: 12px"
>
开发单位厦门高立新鹏软件科技有限公司 技术支持400-990-9112
</a>
</div>
</div> </div>
</template> </template>
@ -145,57 +120,60 @@
import Verify from "vue2-verify"; import Verify from "vue2-verify";
import axios from "axios"; import axios from "axios";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import {decrypt, encrypt} from "@/utils/jsencrypt";
import {getTitleConfig} from "@/api/login"; import {getTitleConfig} from "@/api/login";
import {forceModifyPasswd, modifyPasswd} from "@/api/auth/authAdmin"; import {forceModifyPasswd, modifyPasswd} from "@/api/auth/authAdmin";
export default { export default {
data() { data() {
let validatePwd = (rule, value, callback) => { const validatePass2 = (rule, value, callback) => {
if (value === "") { if (value === '') {
callback(new Error("请输入密码")); callback(new Error('请再次输入密码'));
} else if (value !== this.passwordFormData.newPassword) {
callback(new Error('两次输入密码不一致!'));
} else { } else {
callback(); callback();
} }
}; };
return { return {
ruleForm: { title: "",
userName: "", subTitle: "",
pwd: "", hospName: "",
checked: true,
verificationCode: false,
},
loginForm: { loginForm: {
username: "", username: "",
password: "", password: "",
rememberMe: false,
verificationCode: false,
code: "",
uuid: "",
}, },
rules: { rules: {
userName: [ username: [{ required: true, message: "请输入账号", trigger: "blur" }],
{required: true, message: "请输入登录名", trigger: "blur"}, password: [{ required: true, message: "请输入密码", trigger: "blur" }],
],
pwd: [{validator: validatePwd, trigger: "blur"}],
}, },
isShowPwd: false, // loading: false,
loading: false, // loading isShowPwd: false,
showDialog: false, // dialog redirect: undefined,
redirect: null, //
hospName: "",
title: "福建省XXX医院",
subTitle: "医院UDI管理系统",
passwordFormVisible: false, passwordFormVisible: false,
passwordFormData: { passwordFormData: {
oldPassword: "", oldPassword: "",
newPassword: "", newPassword: "",
confirmPassword: "", confirmPassword: "",
token: "",
}, },
passwordFormDataRules: {
oldPassword: [
{ required: true, message: "请输入旧密码", trigger: "blur" },
],
newPassword: [
{ required: true, message: "请输入新密码", trigger: "blur" },
{ min: 6, message: "密码长度不能小于6位", trigger: "blur" },
],
confirmPassword: [
{ required: true, message: "请确认密码", trigger: "blur" },
{ validator: validatePass2, trigger: "blur" }
],
},
otherQuery: {},
}; };
}, },
methods: { methods: {
//
verifyAlert(text) { verifyAlert(text) {
if (text === "success") { if (text === "success") {
this.loginForm.verificationCode = true; this.loginForm.verificationCode = true;
@ -203,152 +181,87 @@ export default {
this.loginForm.verificationCode = false; this.loginForm.verificationCode = false;
} }
}, },
/* // handleLogin() {
// if (!this.ruleForm.verificationCode) {
// this.$message({
// message: '',
// center: true,
// type: 'warning'
// });
// return;
// }
// this.$refs["ruleForm"].validate((valid) => {
// if (valid) {
// this.loading = true;
// this.$store
// .dispatch("loginName", this.ruleForm)
// .then((response) => {
// this.loading = false;
// if (response.code !== 20000) {
// console.log("--code = " + response.code);
// this.ruleForm.verificationCode = false;
// this.$refs.checkV.refresh();
// this.$message.error(response.message);
// return;
// }
// let path = "/";
// if (this.redirect) {
// path = this.redirect;
// }
// console.log("path = " + path);
// this.$router.push({
// path: "../main",
// });
// // window.location.replace(path);
// // this.showDialog = true
// })
// .catch(() => {
// this.ruleForm.verificationCode = false;
// this.$refs.checkV.refresh();
// this.loading = false;
// });
// } else {
// return false;
// }
// });
// }, */
getCookie() { getCookie() {
const username = Cookies.get("username"); const username = Cookies.get("username");
const password = Cookies.get("password"); const password = Cookies.get("password");
// const rememberMe = Cookies.get('rememberMe') if (username && password) {
this.loginForm = { this.loginForm.username = username;
username: username === undefined ? this.loginForm.username : username, this.loginForm.password = password;
password: }
password === undefined ? this.loginForm.password : decrypt(password),
// rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
}, },
handleLogin() { handleLogin() {
this.$refs.ruleForm.validate((valid) => { if (!this.loginForm.verificationCode) {
this.$message({
message: "请完成滑块验证",
type: "warning",
center: true,
});
return;
}
this.$refs.loginForm.validate((valid) => {
if (valid) { if (valid) {
if (this.loginForm.verificationCode) { this.loading = true;
this.loading = true; this.$store
if (this.loginForm.rememberMe) { .dispatch("Login", this.loginForm)
Cookies.set("username", this.loginForm.username, {expires: 30}); .then((res) => {
Cookies.set("password", encrypt(this.loginForm.password), { this.loading = false;
expires: 30, if (res.code === 20000) {
}); if (res.data.needModifyPassword) {
} else { this.passwordFormVisible = true;
Cookies.remove("username"); this.passwordFormData.token = res.data.token;
Cookies.remove("password");
}
this.$store
.dispatch("Login", this.loginForm)
.then((res) => {
if (res.data.needChangePwd == true) {
this.$confirm('系统检测到您的密码长时间未修改,为保证您的账号安全建议立即修改密码?', '提示', {
confirmButtonText: '立即修改',
cancelButtonText: '忽略',
type: 'warning'
}).then(() => {
this.passwordFormVisible = true;
this.passwordFormData = {
oldPassword: "",
newPassword: "",
confirmPassword: "",
};
}).catch(() => {
this.$router
.push({path: this.redirect || "/"})
.catch((res) => {
});
});
} else { } else {
this.$router this.$router.push({path: this.redirect || "/"});
.push({path: this.redirect || "/"})
.catch((res) => {
});
}
})
.catch((res) => {
this.loading = false;
this.$message.error(res);
if (this.captchaEnabled) {
this.getCode();
} }
}); } else {
} else { this.$message.error(res.msg);
this.$message({ this.$refs.checkV.refresh();
message: "请向右滑动完成验证", }
type: "warning", })
.catch(() => {
this.loading = false;
this.$refs.checkV.refresh();
}); });
} } else {
return false;
} }
}); });
}, },
getTitleConfig() { getTitleConfig() {
getTitleConfig().then(res => { getTitleConfig().then((response) => {
this.title = res.data.title; this.title = response.data.title;
this.subTitle = res.data.subTitle; this.subTitle = response.data.subTitle;
}); });
}, },
passwdSubmit() { passwdSubmit() {
if (this.passwordFormData.newPassword != this.passwordFormData.confirmPassword) { this.$refs.passwordFormData.validate((valid) => {
this.$message.error("新密码与确认密码不一致!!!!"); if (!valid) {
return return false;
} }
if (this.passwordFormData.passWord == this.passwordFormData.newPassword) {
this.$message.error("旧密码与新密码不能相同!!!!"); const data = {
return oldPassword: this.passwordFormData.oldPassword,
} newPassword: this.passwordFormData.newPassword,
this.loading = true; };
forceModifyPasswd(this.passwordFormData).then((response) => {
if (response.code === 20000) { if (this.passwordFormData.token) {
this.loading = false; data.token = this.passwordFormData.token;
this.$confirm('密码重置成功,请点击确定重新登录', '提示', { forceModifyPasswd(data).then((response) => {
confirmButtonText: '确定', if (response.code === 200) {
cancelButtonText: '取消', this.passwordFormVisible = false;
type: 'warning' this.$router.push({path: this.redirect || "/"});
}).then(() => { } else {
this.$store.dispatch('LogOut').then(() => { this.$message.error(response.message);
location.href = process.env.VUE_APP_CONTEXT_PATH; }
})
}).catch(() => {
}); });
} else { } else {
this.$message.error(response.message); modifyPasswd(data).then((response) => {
if (response.code === 200) {
this.passwordFormVisible = false;
} else {
this.$message.error(response.message);
}
});
} }
}); });
}, },
@ -373,129 +286,231 @@ export default {
}; };
</script> </script>
<style type="text/scss" lang="scss"> <style lang="scss" scoped>
@import "../assets/styles/mixin"; @import "../assets/styles/variables.scss";
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container { .login-container {
@include relative; height: 100vh;
background-color: white; width: 100vw;
background-image: url("../assets/login.jpg");
background-size: 100vw 100vh;
height: 100%;
overflow: hidden; overflow: hidden;
position: relative;
input:-webkit-autofill, background-color: #f5f7fa;
input:-webkit-autofill:hover,
input:-webkit-autofill:focus, .login-background {
input:-webkit-autofill:active { display: flex;
-webkit-transition-delay: 99999s;
-webkit-transition: color 99999s ease-out, background-color 99999s ease-out;
}
.item {
width: 20em;
margin-left: 5em;
.el-form-item__content {
display: flex;
flex-flow: row;
}
}
input {
background: transparent;
border: 0;
-webkit-appearance: none;
border-radius: 0;
padding: 0.46rem 0.0666rem 0.16rem 0.2rem;
color: $dark_gray;
height: 100%; height: 100%;
} }
.el-input { .login-left {
display: inline-block; flex: 1;
} background: $primary-gradient;
display: flex;
.tips { align-items: center;
font-size: 14px; justify-content: center;
color: #fff; position: relative;
margin-bottom: 0.13333rem; overflow: hidden;
}
&::before {
.svg-container { content: '';
padding: 0.08rem 0.0666rem 0.08rem 0.2rem; position: absolute;
color: $dark_gray; width: 200%;
vertical-align: middle; height: 200%;
display: inline-block; background: rgba(255, 255, 255, 0.1);
transform: rotate(45deg);
&_login { top: -50%;
font-size: 20px; left: -50%;
}
.login-title-container {
position: relative;
z-index: 2;
text-align: center;
padding: 0 40px;
.main-title {
font-size: 42px;
color: #ffffff;
margin-bottom: 16px;
font-weight: 600;
letter-spacing: 1px;
animation: fadeInUp 0.8s ease;
}
.sub-title {
font-size: 28px;
color: rgba(255, 255, 255, 0.9);
margin-bottom: 30px;
font-weight: 400;
animation: fadeInUp 0.8s ease 0.2s both;
}
.description {
font-size: 16px;
color: rgba(255, 255, 255, 0.8);
line-height: 1.6;
max-width: 500px;
margin: 0 auto;
animation: fadeInUp 0.8s ease 0.4s both;
}
} }
} }
.title { .login-right {
font-size: 26px; width: 500px;
color: #2d3a4b; background-color: #ffffff;
margin: 0 auto 0.5333rem auto; display: flex;
text-align: center; align-items: center;
font-weight: bold; justify-content: center;
margin-bottom: 50px; box-shadow: -5px 0 15px rgba(0, 0, 0, 0.05);
position: relative;
z-index: 2;
.login-form-container {
width: 350px;
padding: 20px;
.login-logo {
text-align: center;
margin-bottom: 20px;
img {
height: 60px;
animation: fadeIn 1s ease;
}
}
.welcome-text {
font-size: 24px;
color: #303133;
text-align: center;
margin-bottom: 30px;
font-weight: 500;
animation: fadeIn 1s ease 0.2s both;
}
.login-form {
animation: fadeIn 1s ease 0.4s both;
.el-form-item {
margin-bottom: 25px;
}
.el-input {
height: 50px;
.el-input__inner {
height: 50px;
line-height: 50px;
padding-left: 15px;
border-radius: $base-border-radius;
&:focus {
border-color: $blue;
box-shadow: 0 0 0 2px rgba($blue, 0.2);
}
}
.el-input__prefix {
left: 15px;
color: #909399;
}
}
.verify-container {
margin-bottom: 30px;
}
.login-button {
width: 100%;
height: 50px;
border-radius: $base-border-radius;
font-size: 16px;
letter-spacing: 1px;
background: $primary-gradient;
border: none;
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba($blue, 0.3);
}
&:active {
transform: translateY(0);
}
}
.login-options {
display: flex;
justify-content: space-between;
margin-top: 15px;
.text-link {
color: $blue;
font-size: 14px;
text-decoration: none;
transition: all 0.3s ease;
&:hover {
color: darken($blue, 10%);
text-decoration: underline;
}
}
}
}
}
} }
.toptitle { .password-toggle {
position: absolute; cursor: pointer;
font-size: 45px; color: #909399;
color: #ffffff;
margin: 120px auto 0.5333rem 180px; &:hover {
text-align: center; color: $blue;
font-weight: bold; }
} }
.topSubtitle { .password-dialog {
position: absolute; .el-dialog__body {
font-size: 45px; padding: 30px 20px;
color: #fcd38b; }
margin: 200px auto 0.5333rem 180px;
text-align: center; .dialog-button {
font-weight: bold; width: 100%;
}
} }
}
.login-form { @keyframes fadeIn {
//@include fxied-center; from {
margin: 0px 60px auto auto; opacity: 0;
width: 50em;
/*background-color: silver;*/
/*background: #fff;*/
padding: 10em 10em 15em 10em;
} }
to {
.el-form-item { opacity: 1;
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 0.0666rem;
color: #454545;
} }
}
.show-pwd { @keyframes fadeInUp {
position: absolute; from {
right: 0.1333rem; opacity: 0;
top: 0.09333rem; transform: translateY(20px);
font-size: 16px;
color: $dark_gray;
cursor: pointer;
} }
to {
.box-card { opacity: 1;
margin-top: -20px; transform: translateY(0);
height: 550px;
width: 490px;
} }
} }
.el-input--mini .el-input__icon { //
line-height: 32px; @media screen and (max-width: 992px) {
.login-container {
.login-left {
display: none;
}
.login-right {
width: 100%;
}
}
} }
</style> </style>

@ -0,0 +1,423 @@
<template>
<div>
<el-card class="list-card">
<div slot="header">
<span>采购申请列表</span>
<el-button
type="text"
icon="el-icon-view"
@click="hideSearch"
>{{ showSearch ? '隐藏搜索' : '显示搜索' }}</el-button>
</div>
<el-form
v-show="showSearch"
:model="filterQuery"
class="search-form"
label-width="100px"
>
<el-row :gutter="16">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="单据号:">
<el-input
v-model="filterQuery.billNo"
placeholder="请输入单据号"
clearable
prefix-icon="el-icon-document"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="单据日期:">
<el-date-picker
v-model="actDateRange"
type="daterange"
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
style="width: 100%"
:picker-options="pickerOptions"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="申购人:">
<el-input
v-model="filterQuery.createByName"
placeholder="请输入申购人"
clearable
prefix-icon="el-icon-user"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="状态:">
<el-select
v-model="filterQuery.status"
placeholder="请选择状态"
clearable
style="width: 100%"
>
<el-option
v-for="(value, key) in statusMap"
:key="key"
:label="value"
:value="key"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="action-group">
<div class="left-actions">
<el-button
type="primary"
icon="el-icon-refresh"
@click="onReset"
>重置</el-button>
<el-button
type="primary"
icon="el-icon-search"
@click="onSubmitFind"
>查询</el-button>
</div>
<div class="right-actions">
<el-button
type="primary"
icon="el-icon-plus"
@click="newDistributionForm()"
:loading="loading"
>新增单据</el-button>
</div>
</div>
<el-table
v-loading="loading"
:data="list"
class="list-table"
@current-change="handleDetail"
border
highlight-current-row
>
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
<el-table-column label="单据号" prop="billNo" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="申购日期" prop="billDate" min-width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.billDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="申购人" prop="createByName" min-width="100" show-overflow-tooltip></el-table-column>
<el-table-column label="申购仓库" prop="targetInvName" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="申购分库" prop="targetDeptName" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="申购说明" prop="remark" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="状态" prop="status" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="(scope.row.status) | statusFilterType">
{{ statusMap[scope.row.status] }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" class-name="operation-column" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
@click.native="newDistributionForm(scope.$index, scope.row)"
circle
title="编辑"
></el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.native.stop="deleteDialog(scope.row)"
circle
title="删除"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="filterQuery.page"
:limit.sync="filterQuery.limit"
@pagination="handleCurrentChange"
class="pagination-container"
></pagination>
</el-card>
<el-card class="list-card" v-if="detailList.length > 0">
<div slot="header">
<span>申购明细</span>
</div>
<el-table
v-loading="loading"
:data="detailList"
class="list-table"
border
highlight-current-row
>
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
<el-table-column label="物资名称" prop="productName" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="规格型号" prop="spec" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="申购数量" prop="count" width="100" align="center"></el-table-column>
<el-table-column label="注册/备案号" prop="zczbhhzbapzbh" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="生产企业" prop="manufactory" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="医疗器械注册人" prop="ylqxzcrbarmc" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="供应商" prop="supName" min-width="150" show-overflow-tooltip></el-table-column>
</el-table>
</el-card>
<el-dialog
:title="formMap[formName]"
:visible.sync="newSpDistributionVisible"
width="80%"
v-if="newSpDistributionVisible"
@close='closeDialog'
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleClose"
class="form-dialog"
>
<pureApplyEdit
:closeDialog="closeDialog"
:idQuery="idQuery"
v-on:cancelDialog="getId"
:isChang="isChang"
></pureApplyEdit>
</el-dialog>
</div>
</template>
<script>
import pureApplyEdit from "./purApplyEditDiaolog";
import {delApply, delApplyDetailAll, inserThrOrderWeb, listApply, listApplyDetail} from "@/api/purchase/purApply";
import {parseTime} from "@/utils/ruoyi";
export default {
name: "ModernPurApply",
components: {
pureApplyEdit
},
data() {
return {
showSearch: true,
pId: null,
filterQuery: {
billAction: null,
billNo: "",
originType: null,
thirdSysFk: "",
page: 1,
limit: 10,
corpName: null,
type: 1,
editStatus: 1,
createByName: "",
status: ""
},
isChang: false,
formName: null,
formMap: {
add: "新增申购单据",
update: "编辑申购单据",
},
statusMap: {
1: "草稿",
2: "未审核",
3: "已审核",
4: "已拒绝"
},
idQuery: {},
total: 0,
thirdSys: [],
thirdSysDetail: null,
busTypes: [],
originTypes: [],
list: [],
detailList: [],
loading: false,
actDateRange: [],
newSpDistributionVisible: false,
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
created() {
this.getList();
},
methods: {
parseTime,
onReset() {
this.filterQuery = {
billNo: "",
thirdSysFk: "",
billFlag: null,
billAction: null,
startDate: null,
endDate: null,
page: 1,
limit: 10,
corpName: null,
type: 1,
editStatus: 1,
createByName: "",
status: ""
};
this.actDateRange = [];
this.getList();
},
onSubmitFind() {
this.filterQuery.page = 1;
if (this.actDateRange && this.actDateRange.length > 0) {
this.filterQuery.startDate = this.actDateRange[0];
this.filterQuery.endDate = this.actDateRange[1];
} else {
this.filterQuery.startDate = null;
this.filterQuery.endDate = null;
}
this.getList();
},
hideSearch() {
this.showSearch = !this.showSearch;
},
getList() {
this.loading = true;
if (this.actDateRange && this.actDateRange.length > 0) {
this.filterQuery.startDate = this.actDateRange[0];
this.filterQuery.endDate = this.actDateRange[1];
}
listApply(this.filterQuery).then(response => {
this.loading = false;
if (response.code === 20000) {
this.list = response.data.list;
this.total = response.data.total;
} else {
this.$message.error(response.msg);
}
}).catch(() => {
this.loading = false;
});
},
handleDetail(row) {
if (!row || !row.id) {
this.detailList = [];
return;
}
this.pId = row.id;
listApplyDetail({id: row.id}).then(response => {
if (response.code === 20000) {
this.detailList = response.data;
} else {
this.$message.error(response.msg);
}
});
},
handleClose() {
this.$confirm('确认关闭?')
.then(_ => {
this.closeDialog();
})
.catch(_ => {});
},
deleteDialog(row) {
this.$confirm('是否确认删除单据号为"' + row.billNo + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.loading = true;
delApplyDetailAll(row.id).then(() => {
delApply(row.id).then(response => {
this.loading = false;
if (response.code === 20000) {
this.$message.success("删除成功");
this.getList();
} else {
this.$message.error(response.msg);
}
}).catch(() => {
this.loading = false;
});
});
});
},
handleCurrentChange() {
this.getList();
},
closeDialog() {
this.newSpDistributionVisible = false;
this.getList();
},
getId(id) {
this.newSpDistributionVisible = false;
this.getList();
},
newDistributionForm(index, row) {
this.formName = row ? "update" : "add";
this.idQuery = row || {};
this.isChang = !!row;
this.newSpDistributionVisible = true;
}
},
filters: {
statusFilterType(status) {
const statusMap = {
1: "info",
2: "warning",
3: "success",
4: "danger"
};
return statusMap[status];
}
}
};
</script>
<style lang="scss" scoped>
.el-card {
margin-bottom: 20px;
}
.form-dialog {
.el-dialog__body {
padding: 20px;
}
}
</style>
Loading…
Cancel
Save