样式修改

dev_招标
yewj 3 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 {
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;
border: none;
overflow: hidden;
&:hover {
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.1);
transform: translateY(-4px);
}
.el-card__header {
padding: 16px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
font-weight: 500;
background-color: rgba($blue, 0.02);
}
.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-item {
@ -209,6 +301,32 @@
.el-table {
border-radius: $base-border-radius;
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 {
background-color: $background-light;
@ -217,17 +335,123 @@
td, th {
padding: 12px 0;
height: 40px; //
line-height: 1.5;
box-sizing: border-box;
}
.el-table__row {
transition: $base-transition;
height: 40px; //
&:hover {
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 {
background-color: rgba($blue, 0.02);
&.el-table--striped .el-table__body tr.el-table__row--striped td {
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 './sidebar.scss';
@import './btn.scss';
@import './ruoyi.scss';
@import './list-page.scss';
@import './tag.scss';
body {
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 {
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
v-loading="loading"
:data="list"
stripe
style="width: 100%"
border
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>
<div class="app-container home">
<div>
<h2>欢迎使用供应商自助管理系统</h2>
<el-divider/>
<div class="welcome-section">
<!-- <h2 class="welcome-title">欢迎使用供应商自助管理系统</h2> -->
<el-divider class="welcome-divider"/>
</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']">
<el-row>
<div class="height-full fl center ml20" style="width: 30%">
<el-image style="border-radius: 4%;width: 80%;height: 80%"
:src="productSvg">
<div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span>
<!-- 数据概览卡片 -->
<div class="dashboard-cards">
<el-row :gutter="20">
<el-col :xs="24" :sm="8" :md="8" :lg="8" v-hasPermi="['home:index:product']">
<el-card class="data-card" shadow="hover">
<div class="card-content">
<div class="card-icon">
<el-image class="icon-image" :src="productSvg"></el-image>
</div>
</el-image>
</div>
<div class="height-full fr center mr20">
<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 class="card-info">
<div class="card-title">已对照产品</div>
<div class="card-value">{{ productCount }}</div>
</div>
</el-image>
</div>
<div class="height-full fr center mr20" @click="linkPage('/remind/invRemindMsg')">
<span class="header d-block">
库存预警
</span>
<span class="d-block mt10" :style="{'font-size': '32px','font-weight': 'bolder',color:'#FF0000'}">
{{ invMsgCount }}
</span>
</div>
</el-row>
</el-card>
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:certWarn']">
<el-row>
<div class="height-full fl center ml20" style="width: 30%">
<el-image style="border-radius: 4%;width: 80%;height: 80%"
:src="certSvg">
<div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" v-hasPermi="['home:index:invWarn']">
<el-card class="data-card warning-card" shadow="hover" @click.native="linkPage('/remind/invRemindMsg')">
<div class="card-content">
<div class="card-icon">
<el-image class="icon-image" :src="invSvg"></el-image>
</div>
<div class="card-info">
<div class="card-title">库存预警</div>
<div class="card-value warning-value">{{ invMsgCount }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" v-hasPermi="['home:index:certWarn']">
<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>
</el-image>
</div>
<div class="height-full fr center mr20" @click="linkPage('/remind/sup/certRemind')">
<span class="header d-block">
资质预警
</span>
<span class="d-block mt10" :style="{'font-size': '32px','font-weight': 'bolder',color:'#FF0000'}"
>
{{ certMsgCount }}
</span>
</div>
</el-row>
</el-card>
<div class="card-info">
<div class="card-title">资质预警</div>
<div class="card-value warning-value">{{ certMsgCount }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</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 slot="header" class="header">
<el-icon class="el-icon-s-management"/>
待办事项{{ `(${todoCount}条)` }}
<div class="fr">
<el-button type="text" style="font-size: 15px;color: unset" @click="getSysMsgTodoList">
<el-icon class="el-icon-refresh"/>
重新加载
</el-button>
<el-button type="text" style="font-size: 15px;color: unset"
@click.stop="">
更多
<el-icon class="el-icon-d-arrow-right"/>
</el-button>
</div>
</div>
<el-table
v-loading="msgLoading"
:data="msgList"
height="calc(100% - 45px)"
stripe
style="">
<el-table-column
type="index"
label="序号"
width="50"/>
<el-table-column
label="消息编码"
prop="code"
width="120"/>
<el-table-column
label="消息类型"
prop="msgTypeName"
width="120"/>
<el-table-column
label="消息内容"
prop="msgContent"
width="280"/>
<el-table-column
label="处理状态"
prop="dealStatusName"
width="120"/>
<el-table-column
label="推送状态"
prop="pushStatusName"
width="120"/>
<el-table-column
label="仓库"
prop="invName"
width="120"/>
<el-table-column
label="部门"
prop="deptName"
width="120"/>
<el-table-column
label="创建时间"
prop="createTime"
width="140"/>
<el-table-column label="操作" width="80" fixed="right">
<template slot-scope="scope">
<el-button
type="text"
@click="linkPage('/system/msg/sysMsgTodo')"
>处理
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card class="grid-item" body-style="padding:0px;height:100%" v-hasPermi="['home:index:ioAudit']">
<div slot="header" class="header">
<el-icon class="el-icon-s-platform"/>
审核送货单{{ `(${orderTotal}条)` }}
<div class="fr">
<el-button type="text" style="font-size: 15px;color: unset" @click="getOrderList">
<el-icon class="el-icon-refresh"/>
重新加载
</el-button>
<el-button type="text" style="font-size: 15px;color: unset"
@click="linkPage('/pur/auditDelivery')">更多
<el-icon class="el-icon-d-arrow-right"/>
</el-button>
</div>
</div>
<el-table
v-loading="orderLoading"
:data="orderList"
height="calc(100% - 45px)"
stripe>
<el-table-column
type="index"
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 class="dashboard-tables">
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="12" :lg="12" v-hasPermi="['home:index:todo']">
<el-card class="table-card" shadow="hover">
<div slot="header" class="card-header">
<div class="header-title">
<i class="el-icon-s-management header-icon"></i>
<span>待办事项</span>
<el-tag size="small" type="info" class="count-tag">{{ todoCount }}</el-tag>
</div>
<div class="header-actions">
<el-button type="text" class="action-button" @click="getSysMsgTodoList">
<i class="el-icon-refresh"></i> 刷新
</el-button>
<el-button type="text" class="action-button">
更多 <i class="el-icon-d-arrow-right"></i>
</el-button>
</div>
</div>
<el-table
v-loading="msgLoading"
:data="msgList"
height="400"
stripe
border
:header-cell-style="{background:'#f5f7fa', color:'#606266'}"
style="width: 100%">
<el-table-column type="index" label="序号" width="50" align="center"/>
<el-table-column label="消息编码" prop="code" width="120" show-overflow-tooltip/>
<el-table-column label="消息类型" prop="msgTypeName" width="120" show-overflow-tooltip/>
<el-table-column label="消息内容" prop="msgContent" min-width="200" show-overflow-tooltip/>
<el-table-column label="处理状态" prop="dealStatusName" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.dealStatus === '0' ? 'warning' : 'success'" size="small">
{{ scope.row.dealStatusName }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime" width="140" show-overflow-tooltip/>
<el-table-column label="操作" width="80" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="linkPage('/system/msg/sysMsgTodo')"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="12" v-hasPermi="['home:index:ioAudit']">
<el-card class="table-card" shadow="hover">
<div slot="header" class="card-header">
<div class="header-title">
<i class="el-icon-s-platform header-icon"></i>
<span>审核送货单</span>
<el-tag size="small" type="info" class="count-tag">{{ orderTotal }}</el-tag>
</div>
<div class="header-actions">
<el-button type="text" class="action-button" @click="getOrderList">
<i class="el-icon-refresh"></i> 刷新
</el-button>
<el-button type="text" class="action-button" @click="linkPage('/pur/auditDelivery')">
更多 <i class="el-icon-d-arrow-right"></i>
</el-button>
</div>
</div>
<el-table
v-loading="orderLoading"
:data="orderList"
height="400"
stripe
border
:header-cell-style="{background:'#f5f7fa', color:'#606266'}"
style="width: 100%">
<el-table-column type="index" label="序号" width="50" align="center"/>
<el-table-column label="送货单号" prop="billNo" width="180" show-overflow-tooltip/>
<el-table-column label="单据类型" prop="billTypeName" width="120" show-overflow-tooltip/>
<el-table-column label="送货单位" prop="fromName" min-width="180" show-overflow-tooltip/>
<el-table-column label="创建时间" prop="createTime" width="140" show-overflow-tooltip/>
<el-table-column label="采购部门" prop="deptName" width="120" show-overflow-tooltip/>
<el-table-column label="收货仓库" prop="invName" width="120" show-overflow-tooltip/>
<el-table-column label="操作" width="80" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="linkPage('/pur/auditDelivery')"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
@ -212,41 +151,36 @@
<script>
import {getOrderList} from "../api/inout/order";
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 {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 {
name: "Index",
data() {
return {
productSvg: productSvg,
invSvg: invSvg,
certSvg: certSvg,
productCount: 0,
invMsgCount: 0,
certMsgCount: 0,
// ==================================================
msgLoading: false,
todoCount: 0,
msgList: [],
// =======================================================================
// ==================================================
orderLoading: false,
orderTotal: 0,
msgList: [],
orderList: [],
// =======================================================================
msgLoading: false,
orderLoading: false,
productSvg,
invSvg,
certSvg
};
},
created() {
this.getProductCount()
this.getInvMsgCount()
this.getCertMsgCount()
this.getSysMsgTodoList()
this.getOrderList()
this.getProductCount();
this.getInvMsgCount();
this.getCertMsgCount();
this.getSysMsgTodoList();
this.getOrderList();
},
methods: {
getProductCount() {
@ -283,191 +217,231 @@ export default {
})
},
linkPage(path) {
console.log(path)
this.$router.push(path)
this.$router.push(path);
},
getSysMsgTodoList() {
this.msgLoading = true
let msgQuery = {
this.msgLoading = true;
sysMsgTodoPage({
page: 1,
limit: 5
}
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
limit: 5,
dealStatus: "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() {
this.orderLoading = true
let orderQuery = {
this.orderLoading = true;
getOrderList({
page: 1,
limit: 5,
status: 10,
vueType: "supDelivery",
}
getOrderList(orderQuery)
.then((res) => {
status: "0",
})
.then((response) => {
this.orderLoading = false;
if (res.code === 20000) {
this.orderList = res.data.list || [];
this.orderTotal = res.data.total || 0;
if (response.code === 20000) {
this.orderList = response.rows;
this.orderTotal = response.total;
} else {
this.$message.error(res.message);
this.$message.error(response.msg);
}
})
.catch((error) => {
this.$message.error(error.message)
.catch(() => {
this.orderLoading = false;
this.orderList = [];
this.orderTotal = 0;
});
},
},
};
</script>
<style scoped lang="scss">
.center {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.el-row .el-card {
margin: 0;
<style lang="scss" scoped>
@import "../assets/styles/variables.scss";
.el-card__body {
padding: 0 !important;
}
}
.grid-item {
.home {
height: 100%;
padding: 15px;
.el-row, .el-col {
height: 100%;
}
.header {
color: #676a6c;
font-size: 20px;
font-weight: bolder;
padding: 20px;
overflow-y: auto;
background-color: #f5f7fa;
//
.welcome-section {
margin-bottom: 24px;
.welcome-title {
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;
width: 100%;
//
.dashboard-cards {
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 {
height: inherit;
display: grid;
grid-gap: 10px;
.el-card {
margin: 0;
//
.dashboard-tables {
.table-card {
margin-bottom: 24px;
border-radius: $base-border-radius;
.card-header {
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);
}
.grid-container2 {
grid-template-columns: repeat(2, 1fr);
}
.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;
//
@media (max-width: 768px) {
.home {
padding: 15px;
.dashboard-cards {
.data-card {
margin-bottom: 15px;
}
}
}
.update-log {
ol {
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;
.dashboard-tables {
.table-card {
margin-bottom: 15px;
}
}
}
}
</style>

@ -1,66 +1,77 @@
<template>
<div>
<el-card class="el-card">
<el-form :model="filterQuery" class="query-form" size="mini" label-width="100px" v-show="showSearch">
<el-row>
<el-col :span="20">
<el-form-item class="query-form-item" label-width="100px" label="UDI码:">
<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码"
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>
<el-col :span="6">
<el-form-item class="query-form-item" label="所属仓库:">
<el-select v-model="filterQuery.invCode" placeholder="请选择所属仓库" clearable="true"
style="width: 90%"
<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">
<span style="float: left">{{ item.name }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="query-form-item" label="货位:">
<el-input v-model="filterQuery.nameCode" placeholder="货位"
style="width: 90%"
clearable="true"></el-input>
<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 :span="6">-->
<!-- <el-form-item class="query-form-item" label="产品标识DI:">-->
<!-- <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-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="供应商名称:">
<el-select
v-model="filterQuery.supId"
filterable
remote
clearable="true"
clearable
reserve-keyword
placeholder="供应商名称"
placeholder="请输入供应商名称"
:remote-method="findMethod"
size="mini"
:loading="corpLoading"
@change="corpChange"
style="width: 90%"
style="width: 100%"
>
<el-option
v-for="item in fromOptions"
@ -68,127 +79,145 @@
:label="item.name"
:value="item.erpId"
>
<span style="float: left">{{ item.name }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="query-form-item" label="生产企业:">
<el-input v-model="filterQuery.ylqxzcrbarmc" placeholder="生产企业"
style="width: 90%"
clearable="true"></el-input>
<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>
<el-col :span="6">
<el-form-item class="query-form-item" label="注册/备案号:">
<el-input v-model="filterQuery.zczbhhzbapzbh" placeholder="注册/备案号"
style="width: 90%"
clearable="true"></el-input>
<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 :span="6">
<el-form-item class="query-form-item" label="物资名称:">
<el-input v-model="filterQuery.cpmctymc" placeholder="物资名称"
style="width: 90%"
clearable="true"></el-input>
<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 :span="6">
<el-form-item class="query-form-item" label="规格型号:">
<el-input v-model="filterQuery.ggxh" placeholder="规格型号"
style="width: 90%"
clearable="true"></el-input>
<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 :span="6">
<el-form-item class="query-form-item" label="批次号:">
<el-input v-model="filterQuery.batchNo" placeholder="批次号"
style="width: 90%"
clearable="true"></el-input>
<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="top-right-btn">
<el-button-group>
<el-button icon="el-icon-view" type="primary" @click="hideSearch">/</el-button>
<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
>
</el-button-group>
>重置</el-button>
<el-button
type="primary"
icon="el-icon-search"
@click="onSubmit"
>查询</el-button>
</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
width="200"></el-table-column>
<el-table-column label="供应商" prop="supName" v-if="showSup" show-overflow-tooltip
width="200"></el-table-column>
<!-- <el-table-column label="部门" prop="deptName" v-if="showSup"-->
<!-- show-overflow-tooltip width="120"></el-table-column>-->
<el-table-column label="操作" width="200" fixed="right">
<el-table
v-loading="loading"
:data="list"
stripe
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="text"
size="small"
type="primary"
size="mini"
icon="el-icon-bell"
@click.native.stop="invRemindSet(scope.row)"
>添加预警设置
</el-button
>
circle
title="添加预警设置"
></el-button>
<el-button
type="text"
size="small"
type="success"
size="mini"
icon="el-icon-view"
@click.native.stop="detailDialog(scope.row)"
>详情
</el-button
>
circle
title="查看详情"
></el-button>
<el-button
type="text"
size="small"
type="danger"
size="mini"
icon="el-icon-delete"
@click.native.stop="deleteDialog(scope.row.id)"
>删除
</el-button
>
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>
@ -199,27 +228,28 @@
:close-on-press-escape="false"
width="85%"
v-if="detailDialogVisible"
class="form-dialog"
>
<invProductsDetail
:inputQuery="inputQuery"
v-on:closeDetailDialog="closeDetailDialog"
:closeDialog="closeDetailDialog"
:row="detailRow"
></invProductsDetail>
</el-dialog>
<el-dialog
title="添加库存预警设置"
:visible.sync="addInvRemindSetDialogVisible"
title="库存预警设置"
:visible.sync="remindSetDialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
width="60%"
v-if="addInvRemindSetDialogVisible"
width="50%"
v-if="remindSetDialogVisible"
class="form-dialog"
>
<addInvRemindSetDialog
:invId="invId"
:closeDialog="closeRemindSetDialog"
:row="detailRow"
></addInvRemindSetDialog>
</el-dialog>
</div>
</template>
@ -232,69 +262,64 @@ import invProductsDetail from "@/views/inventory/InvProductsDetail.vue";
import addInvRemindSetDialog from "@/views/inventory/addInvRemindSetDialog.vue";
export default {
name: "InvProducts",
name: "ModernInvProducts",
components: {
invProductsDetail,
addInvRemindSetDialog
},
data() {
return {
showSearch: true,
showSup: true,
filterQuery: {
udiCode: null,
nameCode: null,
cpmctymc: null,
ggxh: null,
batchNo: null,
supId: null,
zczbhhzbapzbh: null,
ylqxzcrbarmc: null,
invCode: this.$store.getters.locInvCode,
invCode: "",
nameCode: "",
cpmctymc: "",
ggxh: "",
batchNo: "",
udiCode: "",
zczbhhzbapzbh: "",
ylqxzcrbarmc: "",
supId: "",
page: 1,
limit: 10,
limit: 10
},
list: [],
total: 0,
invList: [],
loading: false,
deleteData: {
id: "",
status: 10,
},
corpLoading: false,
dialogVisible: false,
fromOptions: [],
showSup: true,
corpLoading: false,
total: 0,
list: [],
loading: false,
detailDialogVisible: false,
inputQuery: {
cpmctymc: null,
nameCode: null,
batchNo: null,
ggxh: null,
productionDate: null,
expireDate: null,
supId: null,
deptCode: null,
invCode: null,
price:null,
},
addInvRemindSetDialogVisible: null,
invId: null
remindSetDialogVisible: false,
detailRow: null
};
},
created() {
this.getInvList();
this.getList();
},
mounted() {
this.$nextTick(() => {
if (this.$refs.inputRef) {
this.$refs.inputRef.focus();
}
});
},
methods: {
onReset() {
this.$router.push({
path: "",
});
this.filterQuery = {
udiCode: null,
nameCode: null,
cpmctymc: null,
ggxh: null,
batchNo: null,
supId: null,
zczbhhzbapzbh: null,
ylqxzcrbarmc: null,
invCode: this.$store.getters.locInvCode,
invCode: "",
nameCode: "",
cpmctymc: "",
ggxh: "",
batchNo: "",
udiCode: "",
zczbhhzbapzbh: "",
ylqxzcrbarmc: "",
supId: "",
page: 1,
limit: 10,
limit: 10
};
this.getList();
},
@ -305,135 +330,100 @@ export default {
hideSearch() {
this.showSearch = !this.showSearch;
},
handleSizeChange(val) {
this.filterQuery.limit = val;
this.getList();
},
handleCurrentChange(val) {
this.filterQuery.page = val;
this.getList();
enterKey(e) {
this.onSubmit();
},
getList() {
this.loading = true;
getProduct(this.filterQuery).then((res) => {
getInvProduct(this.filterQuery).then(response => {
this.loading = false;
if (res.code === 20000) {
this.list = res.data.list || [];
this.total = res.data.total || 0;
if (response.code === 20000) {
this.list = response.data.list;
this.total = response.data.total;
} else {
this.$message.error(res.message);
this.list = [];
this.total = 0;
this.$message.error(response.msg);
}
}).catch((error) => {
}).catch(() => {
this.loading = false;
this.$message.error(error.message);
this.list = [];
this.total = 0;
})
});
},
getInvList() {
let query = {
advanceType: false,
};
getInvListByUser(query)
.then((response) => {
this.invList = response.data || [];
this.getList();
})
.catch(() => {
});
getInvListByUser().then(response => {
if (response.code === 20000) {
this.invList = response.data;
} else {
this.$message.error(response.msg);
}
});
},
findMethod(key) {
this.corpLoading = true;
this.fromOptions = [];
let params = {
key: key,
corpType: 2,
page: 1,
limit: 20
};
getBasicUnitMaintains(params).then((res) => {
this.corpLoading = false;
this.fromOptions = res.data.list || [];
}).catch(() => {
this.corpLoading = false;
})
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) {
if (!isBlank(value)) {
this.findMethod(value);
}
this.filterQuery.supId = value;
},
detailDialog(row) {
this.detailRow = row;
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() {
this.detailDialogVisible = false;
this.detailRow = null;
},
deleteDialog(id) {
this.$confirm("此操作将永久删除此库存信息,是否继续?", "提示", {
this.$confirm('是否确认删除该条库存记录?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.deleteInvProduct(id);
}).catch(() => {
});
},
deleteInvProduct(id) {
let params = {id: id};
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);
deleteInvProduct(id).then(response => {
if (response.code === 20000) {
this.$message.success("删除成功");
this.getList();
} else {
this.$message.error(response.msg);
}
});
});
},
invRemindSet(row) {
this.invId = row.id;
this.addInvRemindSetDialogVisible = true;
this.detailRow = row;
this.remindSetDialogVisible = true;
},
closeRemindSetDialog() {
this.invId = null;
this.addInvRemindSetDialogVisible = false;
},
},
components: {
invProductsDetail,
addInvRemindSetDialog
},
mounted() {
document.body.ondrop = function (event) {
event.preventDefault();
event.stopPropagation();
};
},
created() {
this.findMethod();
this.getInvList();
this.getList();
},
this.remindSetDialogVisible = false;
this.detailRow = null;
}
}
};
</script>
<style type="text/scss" lang="scss">
</style>
<style lang="scss" scoped>
.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>
<div class="login-container">
<div>
<el-row>
<!-- <h3 class="toptitle">漳州市中医院</h3>-->
<h3 class="toptitle">{{ title }}</h3>
</el-row>
<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 class="login-background">
<div class="login-left">
<div class="login-title-container">
<h1 class="main-title">{{ title }}</h1>
<h2 class="sub-title">{{ subTitle }}</h2>
<p class="description">高效安全的进销存管理系统</p>
</div>
<h3 class="title">用户登录</h3>
<el-form-item prop="username" class="item" style="margin-top: -20px">
<el-input
prefix-icon="el-icon-user"
placeholder="账号"
name="username"
autocomplete="on"
v-model="loginForm.username"
>
<i slot="prefix" class="el-input__icon">
<icon-svg icon-class="user"/>
</i>
</el-input>
</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"
</div>
<div class="login-right">
<div class="login-form-container">
<div class="login-logo">
<img alt="logo" src="@/assets/logo/logoDm.png"/>
</div>
<h2 class="welcome-text">欢迎登录</h2>
<el-form
@submit.native.prevent
class="login-form"
autocomplete="on"
:model="loginForm"
:rules="rules"
ref="loginForm"
label-position="top"
>
<i slot="prefix" class="el-input__icon">
<icon-svg icon-class="pwd"/>
</i>
<i
slot="suffix"
class="el-input__icon"
@click="isShowPwd = !isShowPwd"
>
<icon-svg icon-class="eye"/>
</i>
</el-input>
</el-form-item>
<el-form-item
prop="verificationCode"
class="item"
style="background-color: white"
>
<Verify
ref="checkV"
:showButton="false"
:barSize="{ width: '305px', height: '37px' }"
:vOffset="5"
@success="verifyAlert('success')"
@error="verifyAlert('error')"
:type="3"
></Verify>
</el-form-item>
<div style="text-align: center; margin-top: 15px">
<el-button
type="primary"
style="width: 60%; margin-bottom: 30px"
:loading="loading"
@click.native="handleLogin()"
>登录
</el-button>
</div>
<div style="margin-top: -15px">
<a style="margin-left: 50%; font-size: 12px" :href="'#/register'"
>新用户注册</a
>
<a style="margin-left: 5%; font-size: 12px" :href="'#/forgetPasswd'"
>忘记密码</a
>
<el-form-item prop="username">
<el-input
prefix-icon="el-icon-user"
placeholder="请输入账号"
name="username"
autocomplete="on"
v-model="loginForm.username"
>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
prefix-icon="el-icon-lock"
placeholder="请输入密码"
name="password"
:type="isShowPwd ? 'text' : 'password'"
@keyup.enter.native="handleLogin"
v-model="loginForm.password"
autocomplete="on"
>
<i
slot="suffix"
class="el-input__icon password-toggle"
@click="isShowPwd = !isShowPwd"
>
<i :class="isShowPwd ? 'el-icon-view' : 'el-icon-hide'"></i>
</i>
</el-input>
</el-form-item>
<el-form-item prop="verificationCode" class="verify-container">
<Verify
ref="checkV"
:showButton="false"
:barSize="{ width: '100%', height: '40px' }"
:vOffset="5"
@success="verifyAlert('success')"
@error="verifyAlert('error')"
:type="3"
></Verify>
</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>
</el-card>
</el-form>
</div>
</div>
<el-dialog title="修改密码" :visible.sync="passwordFormVisible" width="85%" top="5vh"
:close-on-click-modal="false"
:show-close="false"
:close-on-press-escape="false">
<el-form :model="passwordFormData" :rules="passwordFormDataRules" ref="passwordFormData">
<el-form-item label="原始密码" prop="old_password">
<el-input type="password" v-model="passwordFormData.oldPassword" auto-complete="off"></el-input>
<!-- 修改密码对话框 -->
<el-dialog
title="修改密码"
:visible.sync="passwordFormVisible"
width="400px"
top="15vh"
: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 label="新密码" prop="new_password">
<el-input type="password" v-model="passwordFormData.newPassword" auto-complete="off"></el-input>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="passwordFormData.newPassword" type="password" placeholder="请输入新密码" show-password></el-input>
</el-form-item>
<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>
<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>
<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>
</template>
@ -145,57 +120,60 @@
import Verify from "vue2-verify";
import axios from "axios";
import Cookies from "js-cookie";
import {decrypt, encrypt} from "@/utils/jsencrypt";
import {getTitleConfig} from "@/api/login";
import {forceModifyPasswd, modifyPasswd} from "@/api/auth/authAdmin";
export default {
data() {
let validatePwd = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入密码"));
const validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== this.passwordFormData.newPassword) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
};
return {
ruleForm: {
userName: "",
pwd: "",
checked: true,
verificationCode: false,
},
title: "",
subTitle: "",
hospName: "",
loginForm: {
username: "",
password: "",
rememberMe: false,
verificationCode: false,
code: "",
uuid: "",
},
rules: {
userName: [
{required: true, message: "请输入登录名", trigger: "blur"},
],
pwd: [{validator: validatePwd, trigger: "blur"}],
username: [{ required: true, message: "请输入账号", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
},
isShowPwd: false, //
loading: false, // loading
showDialog: false, // dialog
redirect: null, //
hospName: "",
title: "福建省XXX医院",
subTitle: "医院UDI管理系统",
loading: false,
isShowPwd: false,
redirect: undefined,
passwordFormVisible: false,
passwordFormData: {
oldPassword: "",
newPassword: "",
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: {
//
verifyAlert(text) {
if (text === "success") {
this.loginForm.verificationCode = true;
@ -203,152 +181,87 @@ export default {
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() {
const username = Cookies.get("username");
const password = Cookies.get("password");
// const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password:
password === undefined ? this.loginForm.password : decrypt(password),
// rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
if (username && password) {
this.loginForm.username = username;
this.loginForm.password = password;
}
},
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 (this.loginForm.verificationCode) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, {expires: 30});
Cookies.set("password", encrypt(this.loginForm.password), {
expires: 30,
});
} else {
Cookies.remove("username");
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) => {
});
});
this.loading = true;
this.$store
.dispatch("Login", this.loginForm)
.then((res) => {
this.loading = false;
if (res.code === 20000) {
if (res.data.needModifyPassword) {
this.passwordFormVisible = true;
this.passwordFormData.token = res.data.token;
} else {
this.$router
.push({path: this.redirect || "/"})
.catch((res) => {
});
}
})
.catch((res) => {
this.loading = false;
this.$message.error(res);
if (this.captchaEnabled) {
this.getCode();
this.$router.push({path: this.redirect || "/"});
}
});
} else {
this.$message({
message: "请向右滑动完成验证",
type: "warning",
} else {
this.$message.error(res.msg);
this.$refs.checkV.refresh();
}
})
.catch(() => {
this.loading = false;
this.$refs.checkV.refresh();
});
}
} else {
return false;
}
});
},
getTitleConfig() {
getTitleConfig().then(res => {
this.title = res.data.title;
this.subTitle = res.data.subTitle;
getTitleConfig().then((response) => {
this.title = response.data.title;
this.subTitle = response.data.subTitle;
});
},
passwdSubmit() {
if (this.passwordFormData.newPassword != this.passwordFormData.confirmPassword) {
this.$message.error("新密码与确认密码不一致!!!!");
return
}
if (this.passwordFormData.passWord == this.passwordFormData.newPassword) {
this.$message.error("旧密码与新密码不能相同!!!!");
return
}
this.loading = true;
forceModifyPasswd(this.passwordFormData).then((response) => {
if (response.code === 20000) {
this.loading = false;
this.$confirm('密码重置成功,请点击确定重新登录', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = process.env.VUE_APP_CONTEXT_PATH;
})
}).catch(() => {
this.$refs.passwordFormData.validate((valid) => {
if (!valid) {
return false;
}
const data = {
oldPassword: this.passwordFormData.oldPassword,
newPassword: this.passwordFormData.newPassword,
};
if (this.passwordFormData.token) {
data.token = this.passwordFormData.token;
forceModifyPasswd(data).then((response) => {
if (response.code === 200) {
this.passwordFormVisible = false;
this.$router.push({path: this.redirect || "/"});
} else {
this.$message.error(response.message);
}
});
} 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>
<style type="text/scss" lang="scss">
@import "../assets/styles/mixin";
<style lang="scss" scoped>
@import "../assets/styles/variables.scss";
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
@include relative;
background-color: white;
background-image: url("../assets/login.jpg");
background-size: 100vw 100vh;
height: 100%;
height: 100vh;
width: 100vw;
overflow: hidden;
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-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;
position: relative;
background-color: #f5f7fa;
.login-background {
display: flex;
height: 100%;
}
.el-input {
display: inline-block;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 0.13333rem;
}
.svg-container {
padding: 0.08rem 0.0666rem 0.08rem 0.2rem;
color: $dark_gray;
vertical-align: middle;
display: inline-block;
&_login {
font-size: 20px;
.login-left {
flex: 1;
background: $primary-gradient;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
width: 200%;
height: 200%;
background: rgba(255, 255, 255, 0.1);
transform: rotate(45deg);
top: -50%;
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 {
font-size: 26px;
color: #2d3a4b;
margin: 0 auto 0.5333rem auto;
text-align: center;
font-weight: bold;
margin-bottom: 50px;
.login-right {
width: 500px;
background-color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
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 {
position: absolute;
font-size: 45px;
color: #ffffff;
margin: 120px auto 0.5333rem 180px;
text-align: center;
font-weight: bold;
.password-toggle {
cursor: pointer;
color: #909399;
&:hover {
color: $blue;
}
}
.topSubtitle {
position: absolute;
font-size: 45px;
color: #fcd38b;
margin: 200px auto 0.5333rem 180px;
text-align: center;
font-weight: bold;
.password-dialog {
.el-dialog__body {
padding: 30px 20px;
}
.dialog-button {
width: 100%;
}
}
}
.login-form {
//@include fxied-center;
margin: 0px 60px auto auto;
width: 50em;
/*background-color: silver;*/
/*background: #fff;*/
padding: 10em 10em 15em 10em;
@keyframes fadeIn {
from {
opacity: 0;
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 0.0666rem;
color: #454545;
to {
opacity: 1;
}
}
.show-pwd {
position: absolute;
right: 0.1333rem;
top: 0.09333rem;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
.box-card {
margin-top: -20px;
height: 550px;
width: 490px;
to {
opacity: 1;
transform: translateY(0);
}
}
.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>

@ -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