第一次提交

This commit is contained in:
2025-07-04 10:37:02 +08:00
commit 5137a64cce
72 changed files with 15660 additions and 0 deletions

53
src/App.vue Normal file
View File

@@ -0,0 +1,53 @@
<template>
<router-view></router-view>
</template>
<style lang="scss">
body {
overflow: hidden;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
<script>
export default {
data () {
return {}
},
created () {
// 解决页面刷新后vuex数据不失效问题
// sessionStorage中store存在重写state
if (sessionStorage.getItem('store')) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem('store'))
)
)
sessionStorage.removeItem('store')
}
// 在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('store', JSON.stringify(this.$store.state))
})
}
}
</script>

BIN
src/assets/daochu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

141
src/assets/excel/Blob.js Normal file
View File

@@ -0,0 +1,141 @@
/* eslint-disable */
require('script-loader!file-saver');
require('script-loader!./Blob');
require('script-loader!xlsx/dist/xlsx.core.min');
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
}
;
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = {v: data[R][C]};
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
console.log('a')
var oo = generateArray(theTable);
var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
console.log(data);
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
}
function formatJson(jsonData) {
console.log(jsonData)
}
export function export_json_to_excel(th, jsonData, defaultTitle) {
/* original data */
var data = jsonData;
data.unshift(th);
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
var title = defaultTitle || '列表'
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
}

View File

@@ -0,0 +1,219 @@
import { saveAs } from 'file-saver'
import XLSX from 'xlsx'
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({
s: {
r: R,
c: outRow.length
},
e: {
r: R + rowspan - 1,
c: outRow.length + colspan - 1
}
});
};
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan)
for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {
s: {
c: 10000000,
r: 10000000
},
e: {
c: 0,
r: 0
}
};
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = {
v: data[R][C]
};
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({
c: C,
r: R
});
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
} else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
var oo = generateArray(theTable);
var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
});
saveAs(new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}), "test.xlsx")
}
export function export_json_to_excel({
multiHeader = [],
header,
data,
filename,
merges = [],
autoWidth = true,
bookType = 'xlsx'
} = {}) {
/* original data */
filename = filename || 'excel-list'
data = [...data]
data.unshift(header);
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i])
}
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = [];
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map(row => row.map(val => {
/*先判断是否为null/undefined*/
if (val == null) {
return {
'wch': 10
};
}
/*再判断是否为中文*/
else if (val.toString().charCodeAt(0) > 255) {
return {
'wch': val.toString().length * 2
};
} else {
return {
'wch': val.toString().length
};
}
}))
/*以第一行为初始值*/
let result = colWidth[0];
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch'];
}
}
}
ws['!cols'] = result;
}
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: 'binary'
});
saveAs(new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}), `${filename}.${bookType}`);
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

View File

@@ -0,0 +1,260 @@
html,
body {
margin: 0;
padding: 0;
color: #333;
box-sizing: border-box;
}
a {
text-decoration: none;
}
/*去掉项目标签*/
ul {
list-style-type: none;
}
.el-main {
padding: 0px !important;
}
.main-container {
width: -moz-available;
width: -webkit-fill-available;
width: stretch;
height: -moz-available;
height: -webkit-fill-available;
height: stretch;
height: 100% !important;
}
.min-height-fill4parent {
height: -moz-available;
height: -webkit-fill-available;
height: stretch;
}
/*成本管理样式*/
.bg_white {
background-color: #FFF
}
.m-t-20 {
margin-top: 20px
}
.m-t-10 {
margin-top: 10px
}
.table_90 {
width: -moz-calc(100% - 24px);
width: -webkit-calc(100% - 24px);
width: calc(100% - 24px);
margin-left: 12px;
margin-right: 12px;
}
.p-t-10 {
padding-top: 10px;
}
.p-b-10 {
padding-bottom: 10px;
}
.border-r-10 {
border-radius: 10px;
}
.text-black {
color: #606266;
}
.text-red {
color: #e73235;
}
.text-green {
color: #38b48b;
}
.m-b-90 {
margin-bottom: 90px;
}
.m-t-10 {
margin-top: 10px;
}
.m-b-20 {
margin-bottom: 20px;
}
.p-t-20 {
padding-top: 20px;
}
.p-b-20 {
padding-bottom: 20px;
}
/*字体居中*/
.text-l {
text-align: left;
}
.text-c {
text-align: center;
}
.text-r {
text-align: right;
}
.f-12 {
font-size: 12px;
}
.header-title {
height: 0;
}
.svg-icon-custom {
width: 16px;
height: 16px;
fill: currentColor;
overflow: hidden;
margin-right: 10px
}
label {
font-weight: bold;
}
/*图片放大样式*/
/*定位*/
.position-r {
position: relative
}
.position-a {
position: absolute;
}
.position-f {
position: fixed;
}
/*知识产权样式*/
.m-20 {
margin: 20px;
}
.p-20 {
padding: 20px;
}
.m-l-10 {
margin-left: 10px;
}
.m-r-10 {
margin-right: 10px;
}
.p-t-20 {
padding-top: 20px;
}
.p-b-20 {
padding-bottom: 20px;
}
.p-l-40 {
padding-left: 40px;
}
.p-r-40 {
padding-right: 40px;
}
.m-l-40 {
margin-left: 40px;
}
.m-r-20 {
margin-right: 20px;
}
.m-r-40 {
margin-right: 40px;
}
.text_blue {
color: #2c74fa;
}
.fr {
float: right;
}
.fl {
float: left;
}
.Cursor {
cursor: pointer;
}
.footer {
position: fixed;
bottom: 0;
z-index: 5;
text-align: right;
right: 0;
box-shadow: -1px 0px 15px 0px #c9ccd4;
}
.search_button {
float: right;
margin-right: 60px;
}
.tips {
// margin-left: 120px;
font-size: 12px;
line-height: 24px;
color: #999999;
margin: 0 !important;
}
.msgbox {
width: 25%;
max-height: 70%;
}
.el-table__body-wrapper::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.el-table__body-wrapper::-webkit-scrollbar-thumb {
border-radius: 6px;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
background-color: #a1a3a9;
border-radius: 6px;
}
.el-table--fluid-height .el-table__fixed,
.el-table--fluid-height .el-table__fixed-right {
bottom: 8px !important;
}

View File

@@ -0,0 +1,13 @@
@font-face {
font-family: 'icon-font';
src: url('../icon/iconfont.woff2') format('woff2'),
url('../icon/iconfont.woff') format('woff'),
url('../icon/iconfont.ttf') format('truetype');
}
.icon-font {
font-family: "icon-font" !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

BIN
src/assets/tianjia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

4
src/components/index.js Normal file
View File

@@ -0,0 +1,4 @@
import Layout from './layout/index'
export {
Layout
}

View File

@@ -0,0 +1,76 @@
<template>
<el-container>
<el-aside :width="leftMenuWidth">
<layout-aside />
</el-aside>
<el-container>
<!-- 头部 -->
<el-header>
<layout-header />
</el-header>
<!-- 主体 -->
<div class="app-main">
<router-view v-slot="{ Component }">
<transition name="router-fade" mode="out-in">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
</div>
</el-container>
</el-container>
</template>
<style lang="scss" scoped>
.el-aside {
background-color: #304156;
z-index: 2000;
}
.el-header {
background-color: rgba(0, 0, 0, .025);
padding: 0;
height: 80px;
}
.app-main {
height: -moz-calc(100vh - 80px);
height: -webkit-calc(100vh - 80px);
height: calc(100vh - 80px);
background-color: #eff2f9;
overflow: scroll;
}
</style>
<script>
import {
LayoutAside,
LayoutHeader
} from '@/components/layout/libs/index'
import {
mapState
} from 'vuex'
export default {
name: 'Layout',
components: {
'layout-aside': LayoutAside,
'layout-header': LayoutHeader
},
computed: {
...mapState('leftAside', {
leftMenuWidth: (state) => state.leftMenuWidth
}),
keyfull() {
return this.$route.fullPath
}
},
data() {
return {
key: this.$route.path,
keepAlivedComponents: {},
}
}
}
</script>

View File

@@ -0,0 +1,8 @@
import LayoutAside from './layout-aside/index.vue'
import LayoutHeader from './layout-header/index.vue'
import LayoutFooter from './layout-footer/index.vue'
export {
LayoutAside,
LayoutHeader,
LayoutFooter
}

View File

@@ -0,0 +1,82 @@
<template>
<div>
<div class="system-title" v-if="!isCollapse">
<img v-if="logo" src="@/assets/logo.png" class="sidebar-logo">
<span>{{ settingsTitle }}</span>
</div>
<div class="system-title" v-else>Cost</div>
<div></div>
<el-scrollbar>
<el-menu
:unique-opened="true"
:default-openeds="defaultOpeneds"
:default-active="defaultActive"
:collapse="isCollapse"
class="left-aside"
@select="handleSelect"
@open="handleOpen"
@close="handleClose"
background-color="rgb(48, 65, 86)"
text-color="#fff"
>
<aside-item v-for="(menu, idx) in menus" :key="idx" :item="menu" />
</el-menu>
</el-scrollbar>
</div>
</template>
<style lang="scss" scoped>
.system-title {
font-size: 14px;
font-weight: bold;
color: #fff;
text-align: center;
padding: 15px 0;
line-height:50px;
background-color:#4178D5;
}
.left-aside {
border-right: 0;
}
.left-aside:not(.el-menu--collapse) {
width: 200px;
}
.sidebar-logo{width: 32px; height: 32px; vertical-align: middle; margin-right: 12px;}
</style>
<script>
import { mapState } from 'vuex'
import AsideItem from './item'
import { title } from '@/settings'
export default {
components: {
'aside-item': AsideItem
},
data () {
return {
settingsTitle: title,
defaultOpeneds: [],
defaultActive: this.$route.name,
logo:true
}
},
computed: {
...mapState({
menus: (state) => state.routes.routes,
isCollapse: (state) => state.leftAside.isCollapse
})
},
watch: {
'$route' (to, from) {
const indexPath = this.$route.matched.map(v => v.name)
this.defaultActive = indexPath.pop()
this.defaultOpeneds = indexPath
}
},
mounted () { },
methods: {
handleSelect (index, indexPath) { },
handleOpen (index, indexPath) { },
handleClose (index, indexPath) { }
}
}
</script>

View File

@@ -0,0 +1,129 @@
<template>
<div v-if="!item.hidden">
<el-sub-menu v-if="showChildren(item)" :index="item.name">
<template #title>
<svg class="icon-font svg-icon-custom" aria-hidden="true" v-if="item.meta.icon" >
<use :xlink:href="item.meta.icon"></use>
</svg>
<!-- <i v-if="item.meta.icon" :class="item.meta.icon"></i> -->
<span>{{ item.meta.title }}</span>
</template>
<aside-item
v-for="(subItem, subIdx) in item.children"
:key="subIdx"
:item="subItem"
/>
</el-sub-menu>
<el-menu-item v-else :index="item.name" @click="handleOpenPage(item)" style="background-color:#1f2d3d">
<i :class="item.meta.icon"></i>
<template #title>{{ item.meta.title }}</template>
</el-menu-item>
</div>
<div v-else>
<aside-item
v-for="(subItem, subIdx) in item.children"
:key="subIdx"
:item="subItem"
/>
</div>
</template>
<style lang="css">
/* 该样式scoped下不生效为不污染全局固采用'>'选择器固定层级选取,不要删除 */
.el-menu--collapse
> div
> .el-submenu
> .el-submenu__title
> .el-submenu__icon-arrow.el-icon-arrow-right {
display: none;
}
</style>
<style lang="scss" scoped>
.el-menu--collapse .el-submenu__title span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
::v-deep([class*=" el-icon-"]),
::v-deep([class^="el-icon-"]) {
color: #fff;
}
::v-deep(.el-menu-item-group__title) {
// background-color: #38b48b;
color: #fff;
height: 38px;
font-size: 16px;
line-height: 38px;
}
::v-deep(.el-submenu__title) {
font-size: 16px;
height: 50px;
line-height: 50px;
}
::v-deep(.el-submenu .el-menu-item) {
padding-left: 40px !important;
background-color:#1f2d3d!important;
color:rgb(191, 203, 217);
}
::v-deep(.el-menu .el-menu-item:hover) {
padding-left: 40px !important;
background-color:#4178d5!important;
color:rgb(191, 203, 217);
}
::v-deep(.el-menu-item.submenu-title-noDropdown) {
padding-left: 20px !important;
}
::v-deep(.el-menu-item.is-active) {
color: #fff !important;
background-color: #4178d5 !important;
}
::v-deep(.el-sub-menu__title){
border-bottom: 1px solid #1f2d3d;
background-color:rgb(48, 65, 86)!important;
}
::v-deep(.el-sub-menu.is-active .el-sub-menu__title){
border-bottom: 1px solid #1f2d3d;
}
::v-deep(.is-active .el-sub-menu .el-menu){
background-color:rgb(48, 65, 86)!important;
}
</style>
<script>
export default {
name: 'AsideItem',
data () {
return {}
},
props: {
item: {
type: Object,
required: true,
default: () => {
return {}
}
}
},
methods: {
showChildren (menu) {
if (typeof menu.children === 'undefined' || menu.children.length <= 0) return false
if (menu.children.length === 1 && menu.children[0].hidden) return false
return true
},
submenuTitleNoDropdown (menu) {
if (typeof menu.children === 'undefined' || menu.children.length <= 0) return false
if (menu.children.length === 1 && menu.children[0].hidden) return true
return false
},
handleOpenPage (item) {
this.$router.push({
path: item.path
})
}
}
}
</script>

View File

@@ -0,0 +1,6 @@
<template>
<div>footer</div>
</template>
<script>
export default {}
</script>

View File

@@ -0,0 +1,319 @@
<template>
<el-row class="header-container">
<el-col :span="21" class="tags-container">
<div class="left-menu-collapse" @click="changeCollapse">
<i :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"></i>
</div>
<div class="tags-box">
<el-tag
v-for="(tag, idx) in tags"
:key="idx"
:disable-transitions="false"
@click="handleClick(tag)"
@close="handleCloseTag(idx, tag.fullPath)"
:closable="tag.name !== 'Index' && tag.name !== 'ProductHomelist'"
:class="fullPath === tag.fullPath ? 'tag active' : 'tag'"
>{{ tag.meta.title }}</el-tag>
</div>
</el-col>
<el-col :span="3" class="text-r p-t-20">
<!-- <i class="el-icon-message f_18 m-r-38 position-r">
<span class="news-number">20</span>
</i>-->
<el-dropdown :hide-on-click="false">
<span class="el-dropdown-link">
<span class="f_14">{{ userInfo.staff_name }}</span>
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleNavigatorPersonCenter">个人资料</el-dropdown-item>
<el-dropdown-item divided @click="handleSigninOut">
<i class="el-icon-switch-button"></i>
退出
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
.header-container {
height: 100%;
background-color: #304156;
padding-right: 20px;
}
.tags-container {
padding: 0 20px;
}
.left-menu-collapse {
position: absolute;
top: 50%;
left: 10px;
transform: translateY(-50%);
width: 33px;
height: 33px;
text-align: center;
line-height: 33px;
cursor: pointer;
color: #c0ccd8;
}
.tags-box {
position: absolute;
top: 50%;
left: 50px;
transform: translateY(-50%);
}
::v-deep(.tag) {
color: #c0ccd8;
border: 1px solid #293749;
margin-right: 10px;
background-color: #293749;
cursor: pointer;
padding: 0px 10px 0px 10px;
height: 38px !important;
line-height: 38px;
}
.tag.active {
background-color: #344964 !important;
color: FFF;
font-size: 14px;
border: 1px solid #4178d5;
}
::v-deep(.el-tag .el-icon-close) {
padding-left: 20px;
}
::v-deep(.el-tag .el-tag__close:hover) {
background-color: transparent !important;
}
// ::v-deep([class*=" el-icon-"]) {
// color: #555;
// }
::v-deep(.el-header) {
padding: 0px 0px 0px 20px;
}
.news-number {
position: absolute;
top: -50%;
left: 50%;
background-color: #fc8568;
padding: 2px 5px;
color: #fff;
font-size: 6px;
border-radius: 18px;
}
.el-dropdown {
color: #c0ccd8 !important;
}
.el-dropdown .el-dropdown-selfdefine {
line-height: 40px !important;
color: #c0ccd8 !important;
}
</style>
<script>
import { mapActions, mapState } from 'vuex'
import { setNotLoggedIn } from '@/utils/auth'
export default {
data() {
return {
fullPath: '/index',
tags: [
{
fullPath: '/index/oindex',
hash: '',
query: {},
name: 'OldCost',
path: '/index/oindex',
params: {},
matched: [
{
path: '/index',
redirect: '',
name: 'NewCost',
meta: {
title: 'OPD211',
permission: ['NewCost.OldCost', 'NewCost.NewCostFinance', 'NewCost.NewCostLog']
},
props: {
default: false
},
children: [
{
id: 641,
path: '/index/oindex',
name: 'OldCost',
meta: {
title: '老产品成本管理'
},
hidden: false,
redirect: ''
},
{
id: 619,
path: '/index/log',
name: 'NewCostLog',
meta: {
title: '日志管理'
},
hidden: true,
redirect: ''
}
],
instances: {},
leaveGuards: {
'Set(0)': []
},
updateGuards: {
'Set(0)': []
},
enterCallbacks: {},
components: {
default: {
name: 'Layout',
components: {
'layout-aside': {
components: {
'aside-item': {
name: 'AsideItem',
props: {
item: {
0: false,
1: true,
required: true
}
},
methods: {},
__scopeId: 'data-v-0705fa1e',
__file: 'src/components/layout/libs/layout-aside/item.vue',
__hmrId: '0705fa1e'
}
},
computed: {},
watch: {},
methods: {},
__scopeId: 'data-v-357d3738',
__file: 'src/components/layout/libs/layout-aside/index.vue',
__hmrId: '357d3738'
},
'layout-header': {
computed: {},
watch: {},
methods: {},
__scopeId: 'data-v-6c46a177',
__file: 'src/components/layout/libs/layout-header/index.vue',
__hmrId: '6c46a177'
}
},
computed: {},
__scopeId: 'data-v-dd2fd986',
__file: 'src/components/layout/index.vue',
__hmrId: 'dd2fd986'
}
}
},
{
path: '/index/oindex',
redirect: '',
name: 'OldCost',
meta: {
title: '老产品成本管理'
},
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {
'Set(0)': []
},
updateGuards: {
'Set(0)': []
},
enterCallbacks: {},
components: {
default: {
computed: {},
methods: {},
__scopeId: 'data-v-1e7a7aba',
__file: 'src/views/index/oindex.vue',
__hmrId: '1e7a7aba'
}
}
}
],
meta: {
title: '老产品成本管理',
permission: ['NewCost.OldCost', 'NewCost.NewCostFinance', 'NewCost.NewCostLog']
},
redirectedFrom: {
fullPath: '/index/oindex',
hash: '',
query: {},
path: '/index/oindex',
params: {},
matched: [],
meta: {},
href: '/index/oindex'
},
href: '/index/oindex'
}
]
}
},
computed: {
...mapState({
// 取出页面标签
userInfo: state => state.user.userInfo,
// tags: state => state.topNavTag.tags,
isCollapse: state => state.leftAside.isCollapse
})
},
watch: {
// 监听路由变化
$route(to, from) {
this.fullPath = to.fullPath
}
},
created() {
this.fullPath = this.$route.fullPath
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag',
// 展开收缩左侧菜单栏
changeCollapse: 'leftAside/changeCollapse'
}),
// 页面标签点击事件
handleClick(tag) {
this.$router.push(tag)
},
// 页面标签点击事件
// handleCloseTag(idx, url) {
// console.log(idx, url)
// },
// 个人中心
handleNavigatorPersonCenter() {
window.open(process.env.VUE_APP_SSO_BASEURL + 'user/index.html')
},
// 退出
handleSigninOut() {
this.$http.get('login/logout').then(r => {
if (r.errno === 0) {
setNotLoggedIn()
this.$store.replaceState({})
this.$router.push({
path: '/login'
})
}
})
}
}
}
</script>

9
src/icons/index.js Normal file
View File

@@ -0,0 +1,9 @@
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

64
src/main.js Normal file
View File

@@ -0,0 +1,64 @@
import {
createApp
} from 'vue'
import ElementPlus from 'element-plus'
import App from './App.vue'
import router from './router'
import store from './store'
import Request from '@/utils/request'
import '@/router/permission.js'
import 'element-plus/dist/index.css'
import {
ElMessage
} from 'element-plus'
import locale from 'element-plus/lib/locale/lang/zh-cn' //需要新加的代码
import {
defineRule,
configure
} from 'vee-validate'
import all from '@vee-validate/rules'
import allValid from '@/utils/validate'
import '@/assets/style/global.scss'
import '@/assets/style/icon.scss'
import '@/utils/iconfont.js'
import 'xe-utils'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
configure({
validateOnBlur: true, // controls if `blur` events should trigger validation with `handleChange` handler
validateOnChange: true, // controls if `change` events should trigger validation with `handleChange` handler
validateOnInput: false, // controls if `input` events should trigger validation with `handleChange` handler
validateOnModelUpdate: true // controls if `update:modelValue` events should trigger validation with `handleChange` handler
})
Object.keys(all).forEach(rule => {
defineRule(rule, all[rule])
})
Object.keys(allValid).forEach(rule => {
defineRule(rule, allValid[rule])
})
const app = createApp(App)
app.use(store)
app.use(router)
app.use(ElMessage)
app.use(ElementPlus, {
locale
}) //需要改变的地方加入locale
app.use(VXETable)
app.config.globalProperties.$http = new Request()
// app.config.globalProperties.$message = ElMessage
app.mount('#app')
// 注册一个全局自定义指令 `v-allow` 配合路由meta.permission信息控制节点显示权限
app.directive('allow', {
mounted(el, binding) {
const permission = binding.instance.$route.meta.permission
if (!permission.includes(binding.value)) {
el.parentNode.removeChild(el)
}
}
})

55
src/router/index.js Normal file
View File

@@ -0,0 +1,55 @@
import {
createRouter,
createWebHistory
} from 'vue-router'
import {
Layout
} from '@/components/'
export const staticRoutes = [
{
path: '/',
name: 'Main',
component: Layout,
meta: {
title: '老成本管理',
icon: ''
},
hidden: true,
children: [{
path: '/oindex',
name: 'NewCostList',
meta: {
title: '老成本管理',
icon: 'el-icon-s-home'
},
hidden: true,
component: () => import('@/views/index/oindex')
}]
},
{
path: '/login',
name: 'Login',
hidden: true,
component: () => import('@/views/login/index'),
meta: {
title: '登录页'
}
},
{
path: '/404',
name: '404',
hidden: true,
component: () => import('@/views/public/404'),
meta: {
title: '页面未找到'
}
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: staticRoutes
})
export default router

55
src/router/permission.js Normal file
View File

@@ -0,0 +1,55 @@
import router from '@/router'
import store from '@/store'
import { title as settingsTitle } from '@/settings'
import { checkSignedInStatus, setNotLoggedIn } from '@/utils/auth'
let loadedDynamicRoutes = false // 是否已加载动态路由
const whiteList = ['/login']
router.beforeEach(async (to, from, next) => {
// 网页title跟随路由title
document.title = settingsTitle + '-' + to.meta.title
if (checkSignedInStatus()) {
// 身份验证通过
if (to.path !== '/login') { // 不在登录页面,正常进入相应页面
if (loadedDynamicRoutes) {
store.dispatch('topNavTag/addNavTag', to) // 顶部页面标签处理
next()
} else {
try {
// 获取用户信息
await store.dispatch('user/getUserInfo')
// 获取用户权限列表
const authList = store.getters['user/getUserAuthList']
// 获取用户有权限操作权限的路由
const accessRoutes = await store.dispatch('routes/generateRoutes', authList)
// 动态添加路由
accessRoutes.forEach(route => {
router.addRoute(route)
})
// 设为已加载动态路由
loadedDynamicRoutes = true
// 确保动态添加的路由已经被完全加载上去并替换浏览器路由使浏览器没有浏览历史可回退
next({ ...to, replace: true })
} catch (error) {
// 设为非登录状态
setNotLoggedIn()
next('/login')
}
}
} else { // 在登录页面
next({ path: '/' })
}
} else { // 身份验证不过
// 设为非登录状态
setNotLoggedIn()
if (whiteList.indexOf(to.path) !== -1) { // 处于不用登录页面
next()
} else {
next('/login')
}
}
})

3
src/settings.js Normal file
View File

@@ -0,0 +1,3 @@
module.exports = {
title: 'OPD211'
}

19
src/store/index.js Normal file
View File

@@ -0,0 +1,19 @@
import {
createStore
} from 'vuex'
import leftAside from './modules/leftAside'
import topNavTag from './modules/topNavTag'
import routes from './modules/routes'
import user from './modules/user'
export default createStore({
state: {},
mutations: {},
actions: {},
modules: {
leftAside,
topNavTag,
routes,
user
}
})

View File

@@ -0,0 +1,28 @@
const state = {
leftMenuWidth: '200px',
isCollapse: false
}
const mutations = {
CHANGE_COLLAPSE: (state) => {
state.isCollapse = !state.isCollapse
if (state.isCollapse) {
state.leftMenuWidth = 'auto'
} else {
state.leftMenuWidth = '200px'
}
}
}
const actions = {
changeCollapse (context) {
context.commit('CHANGE_COLLAPSE')
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -0,0 +1,84 @@
import { staticRoutes } from '@/router'
import Request from '@/utils/request'
import Layout from '@/components/layout/index'
// 从服务器获取菜单
async function fetchAsyncRoutes4Server() {
return (new Request()).mock(true).get('menu/index').then(r => {
if (r.errno !== 0) {
return []
}
let ar =[{"id":616,"pid":0,"menu_title":"OPD211","menu_name":"NewCost","menu_path":"\/index","menu_component":"\/layout","redirect":"","sort":1,"type":1,"is_menu":1,"component":"\/layout","name":"NewCost","path":"\/index","title":"OPD211","meta":{"title":"OPD211"},"hidden":false,"alwaysshow":true,"children":[{"id":617,"pid":616,"menu_title":"老成本管理","menu_name":"NewCostList","menu_path":"\/index\/index","menu_component":"\/index\/index","redirect":"","sort":2,"type":1,"is_menu":1,"component":"\/index\/index","name":"NewCostList","path":"\/index\/index","title":"老成本管理","meta":{"title":"老成本管理"},"hidden":false,"alwaysshow":false},{"id":619,"pid":616,"menu_title":"日志管理","menu_name":"NewCostLog","menu_path":"\/index\/log","menu_component":"\/index\/log","redirect":"","sort":4,"type":1,"is_menu":1,"component":"\/index\/log","name":"NewCostLog","path":"\/index\/log","title":"日志管理","meta":{"title":"日志管理"},"hidden":true,"alwaysshow":false}]}]
// ar.children.push(r.data.children[2])
console.log(ar)
return ar
})
// return ar
}
// 组装路由结构
function buildTreeAsyncRoutes (routes, authList) {
const menus = []
routes.forEach(item => {
const it = { id: item.id, path: item.path, name: item.name, meta: item.meta, alwaysShow: item.alwaysShow, hidden: item.hidden }
if (item.redirect != null) {
it.redirect = item.redirect
}
if (item.component && authList.indexOf(item.id) >= 0) {
if (item.component === '/layout') {
it.component = Layout
} else {
it.component = () => import('@/views' + item.component)
}
if (item.children && item.children.length) {
item.children.forEach(v => {
if (!it.meta.permission) {
it.meta.permission = []
}
if (item.path.startsWith('/')) {
item.path = item.path.substring(1)
}
if (authList.indexOf(v.id) >= 0) {
it.meta.permission.push(item.name + '.' + v.name)
}
})
it.children = buildTreeAsyncRoutes(item.children, authList)
}
menus.push(it)
}
})
return menus
}
const state = {
routes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.routes = routes
}
}
const actions = {
async generateRoutes (context, authList) {
// 服务器获取菜单
const routes = await fetchAsyncRoutes4Server()
// 权限过滤
// const accessRoutes = routes.filter(v => authList.indexOf(v.id) >= 0)
// 组装路由
const treeRoutes = buildTreeAsyncRoutes(routes, authList)
const mergeTreeRoutes = staticRoutes.concat(treeRoutes)
context.commit('SET_ROUTES', mergeTreeRoutes)
return mergeTreeRoutes
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -0,0 +1,68 @@
import router from '@/router'
const state = {
tags: [
// 默认打开路由标签
{ fullPath: '/index/index', name: 'NewCostList', meta: { title: '成本管理' } }
] // 标签
}
const mutations = {
// 新增标签
ADD_NAV_TAG: (state, tag) => {
state.tags.push(tag)
},
// 替换标签
REPLACE_NAV_TAG: (state, tag) => {
const index = state.tags.findIndex(it => it.fullPath === tag.fullPath)
// const index = state.tags.findIndex(it => it.path === tag.path)
state.tags.splice(index, 1, tag)
},
// 删除标签
RM_NAV_TAG: (state, index) => {
state.tags = state.tags.filter((it, i) => {
return i !== index || it.name === 'NewCostList'
})
}
}
const actions = {
// 新增标签
addNavTag: (context, tag) => {
// 跳转至新打开页面
if (tag.name == '404') {
return false
}
// router.push({ path: tag.fullPath })
// if (!context.state.tags.some(v => v.name === tag.name)) {
if (!context.state.tags.some(v => v.fullPath === tag.fullPath)) {
// 标签栏没有,新增页面标签
context.commit('ADD_NAV_TAG', tag)
} else {
// 标签栏有,替换标签
context.commit('REPLACE_NAV_TAG', tag)
}
},
// 删除标签
removeNavTag: (context, index) => {
let nextIndex = index - 1
var overallVar = context
if (context.state.tags.length - 1 > index) {
nextIndex = index + 1
}
// 最后一个页面标签不允许删除
if (nextIndex === -1) return false
// router.push({ path: context.state.tags[nextIndex].path })
router.push(context.state.tags[nextIndex]);
context.commit('RM_NAV_TAG', index)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

68
src/store/modules/user.js Normal file
View File

@@ -0,0 +1,68 @@
import { toRaw } from 'vue'
import Request from '@/utils/request'
const state = {
userInfo: {}
}
const getters = {
// 获取用户菜单权限
getUserAuthList: state => {
if (state.userInfo.length <= 0) {
return []
}
if (typeof state.userInfo.auth_list === 'undefined') {
return []
}
return toRaw(state.userInfo.auth_list)
}
}
const mutations = {
SET_USER_INFO: (state, user) => {
state.userInfo = user
}
}
const actions = {
// 设置用户信息
setUserInfo (context, user) {
context.commit('SET_USER_INFO', user)
},
// 获取用户信息
getUserInfo (context) {
return new Promise((resolve, reject) => {
if (context.state.userInfo.length <= 0 || typeof context.state.userInfo.auth_list === 'undefined') {
// 服务器获取用户信息
return (new Request()).get('login/getOssInfo')
.then(r => {
const { errno, data, errmsg } = r
if (errno !== 0) {
if (errno == 500){
alert(errmsg)
setTimeout(() => window.location.href="/login")
}else{
reject(errmsg)
}
}
context.commit('SET_USER_INFO', data)
resolve(data)
})
.catch(e => {
reject(e)
})
}
resolve(toRaw(context.state.userInfo))
})
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

16
src/utils/auth.js Normal file
View File

@@ -0,0 +1,16 @@
import Cookies from 'js-cookie'
const signedInKey = 's_pass'
// 设置已登录状态cookie
export function setSignedIn () {
return Cookies.set(signedInKey, 1)
}
// 判断是否已登录
export function checkSignedInStatus () {
return (Cookies.get(signedInKey) * 1) === 1
}
// 删除登录状态cookie
export function setNotLoggedIn () {
sessionStorage.clear()
return Cookies.remove(signedInKey)
}

69
src/utils/common.js Normal file
View File

@@ -0,0 +1,69 @@
// 深拷贝对象
export function copyObj(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
const isArray = Array.isArray(obj)
const cloneObj = isArray ? [] : {}
for (const key in obj) {
cloneObj[key] = isObject(obj[key]) ? copyObj(obj[key]) : obj[key]
}
return cloneObj
}
// 赋值对象
export function assignObj(obj1, obj2) {
for (const key in obj1, obj2) {
if (isObject(obj2[key])) {
assignObj(obj1[key], obj2[key])
} else {
obj1[key] = obj2[key]
}
}
}
export function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
//转义
export function HTMLDecode(str){
var s = ''
if (str.length == 0) return ''
s = str.replace(/&lt;/g, '<')
s = s.replace(/&amp;/g, '&')
s = s.replace(/&gt;/g, '>')
s = s.replace(/&#39;/g, "\'")
s = s.replace(/&quot;/g, '"')
return s
}
export function HTMLEncode(str){
var s = ''
if (str.length == 0) return ''
s = str.replace(/&/g, '&amp;')
s = s.replace(/</g, '&lt;')
s = s.replace(/>/g, '&gt;')
s = s.replace(/\'/g, '&#39;')
s = s.replace(/\"/g, '&quot;')
return s
}
//正则
export function dealInputVal(value) {
value = value.replace(/^0*(0\.|[1-9])/, "$1");
value = value.replace(/[^\d.]/g, ""); //清除"数字"和"."以外的字符
value = value.replace(/^\./g, ""); //验证第一个字符是数字而不是字符
value = value.replace(/\.{1,}/g, "."); //只保留第一个.清除多余的
value = value
.replace(".", "$#$")
.replace(/\./g, "")
.replace("$#$", ".");
value = value.replace(/^()*(\d*)\.(\d\d).*$/, "$1$2.$3"); //只能输入两个小数
value =
value.indexOf(".") > 0
? value.split(".")[0].substring(0, 10) + "." + value.split(".")[1]
: value.substring(0, 10);
return value;
}

32
src/utils/exportExcel.js Normal file
View File

@@ -0,0 +1,32 @@
import axios from 'axios'
const exportExcel = (url, params) => {
console.log('我是公共的方法' + url)
const apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
axios.post(process.env.VUE_APP_API_BASEURL + apiVersion + url, params, {
responseType: 'blob',
headers: {
// 'X-Token': getToken(),
'Content-Type': 'application/json;charset=utf-8'
}
}).then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const nameStr = decodeURI(escape(JSON.parse(res.headers['content-disposition'].split(';')[1].split('=')[1])))
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
}
export { exportExcel }

1
src/utils/iconfont.js Normal file

File diff suppressed because one or more lines are too long

117
src/utils/index.js Normal file
View File

@@ -0,0 +1,117 @@
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string | null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string')) {
if ((/^[0-9]+$/.test(time))) {
// support "1548221490638"
time = parseInt(time)
} else {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
time = time.replace(new RegExp(/-/gm), '/')
}
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
return value.toString().padStart(2, '0')
})
return time_str
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}

141
src/utils/request.js Normal file
View File

@@ -0,0 +1,141 @@
import axios from 'axios'
import router from '@/router'
import {
ElLoading,
ElMessage
} from 'element-plus'
import {
setNotLoggedIn
} from '@/utils/auth'
export default class Request {
http
isMock = false
isJWT = false
loadingInstance
loading = true
constructor() {
const apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
this.http = axios.create({
baseURL: process.env.VUE_APP_API_BASEURL + apiVersion + '/',
timeout: 600000,
withCredentials: true
})
this.interceptors()
}
mock(mock) {
this.isMock = mock
return this
}
JWT() {
this.isJWT = true
// this.http.defaults.headers.common['isJWT'] = true;
}
showLoading(show) {
this.loading = show
return this
}
post(path, params) {
let config = {}
if (this.isMock) config = { baseURL: process.env.VUE_APP_API_MOCK }
return new Promise((resolve, reject) => {
this.http.post(path, params, config).then((r) => {
resolve(r)
}).catch((e) => {
reject(e.message)
})
})
}
get(path, params) {
const data = {
params: params
}
if (this.isMock) data.baseURL = process.env.VUE_APP_API_MOCK
return new Promise((resolve, reject) => {
this.http.get(path, data).then((r) => {
resolve(r)
}).catch((e) => {
reject(e.message)
})
})
}
put(path, params) {
let config = {}
if (this.isMock) config = { baseURL: process.env.VUE_APP_API_MOCK }
return new Promise((resolve, reject) => {
this.http.put(path, params, config).then((r) => {
resolve(r)
}).catch((e) => {
reject(e.message)
})
})
}
delete(path) {
let config = {}
if (this.isMock) config = { baseURL: process.env.VUE_APP_API_MOCK }
return new Promise((resolve, reject) => {
this.http.delete(path, config).then((r) => {
resolve(r)
}).catch((e) => {
reject(e.message)
})
})
}
interceptors() {
this.http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
// 添加请求拦截器
this.http.interceptors.request.use((config) => {
// 显示loading
if (this.loading) {
this.loadingInstance = ElLoading.service({
fullscreen: true
})
}
if (this.isJWT) {
config.headers.Authorization = 'token'
}
return config
}, (error) => {
// 请求错误
return Promise.reject(error)
})
// 添加响应拦截器
this.http.interceptors.response.use((response) => {
// 关闭loading
if (this.loading) this.loadingInstance.close()
if (response.status === 200) {
if(response.data.status !== 200 && response.data.status !== 99999){
if(response.data.message){
ElMessage.error(response.data.message)
}
}
if (response.data.errno === 2003) {
setNotLoggedIn() // 设置未登录
router.replace('/login')
return
}
return response.data
} else {
console.error(response)
}
}, (error) => {
// 关闭loading
setTimeout(() => {
if (this.loading) this.loadingInstance.close()
}, 3000)
// 响应错误
return Promise.reject(error)
})
}
}

33
src/utils/storage.js Normal file
View File

@@ -0,0 +1,33 @@
// session操作
const sessionData = function (method, url, name, obj) {
/*
* 参数说明:
* methodget获取set存入或覆盖clean清除
* name:session的名称
* obj:存入的内容,可以是任意类型
* */
switch (method) {
case 'get':
if (sessionStorage.getItem(url + name + '_obj')) {
return JSON.parse(sessionStorage.getItem(url + name + '_obj'));
} else if (sessionStorage.getItem(url + name + '_str')) {
return sessionStorage.getItem(url + name + '_str');
} else {
return null
}
case 'set':
sessionData('clean', url + name);
if (typeof obj == 'object') {
sessionStorage.setItem(url+ name + '_obj', JSON.stringify(obj));
} else {
sessionStorage.setItem(url + name + '_str', obj);
}
return true;
case 'clean':
sessionStorage.removeItem(url + name + '_obj');
sessionStorage.removeItem(url + name + '_str');
return true;
}
};
export {sessionData}

58
src/utils/upload.js Normal file
View File

@@ -0,0 +1,58 @@
// An highlighted block
import COS from 'cos-js-sdk-v5'
import { getSecret } from '@/api/upload'
export default function upload(file, config, callback) {
if (typeof config.isPublic === 'undefined') {
config.isPublic = true
}
getSecret({
type: config.type,
path: config.path,
isPublic: config.isPublic ? config.isPublic : false
}).then(response => {
const data = response.data
const cos = new COS({
getAuthorization: function(options, callback) {
callback({
TmpSecretId: data.tmpSecretId,
TmpSecretKey: data.tmpSecretKey,
XCosSecurityToken: data.sessionToken,
ExpiredTime: data.expiredTime
})
}
})
return {
cos: cos,
dir: data.url,
bucket: data.bucket,
region: data.region
}
}).then(data => {
const cos = data.cos
const dir = data.dir
const bucket = data.bucket
const region = data.region
const url = cos.getObjectUrl({
Bucket: bucket,
Region: region,
Key: `${dir}/${file.name}`,
Sign: false
}, function(data) {
cos.putObject({
Bucket: bucket,
Region: region,
Key: `${dir}/${file.name}`,
Body: file
}, function(data) {
if (config.isPublic) {
callback(url.replace(/^http(s)?:\/\/(.*?)\//, 'https://www.baidu.com/'))
} else {
callback(url)
}
})
})
})
}

79
src/utils/util.js Normal file
View File

@@ -0,0 +1,79 @@
const formatDate = function (time, format) {
var t = new Date(time)
var tf = function(i) {
return (i < 10 ? "0" : "") + i
}
return format.replace(/Y|m|d|H|i|s/g, function(a) {
switch (a) {
case "Y":
return tf(t.getFullYear())
case "m":
return tf(t.getMonth() + 1)
case "d":
return tf(t.getDate())
case "H":
return tf(t.getMinutes())
case "i":
return tf(t.getHours())
case "s":
return tf(t.getSeconds())
}
})
}
// 时间戳转日期
const timestampToTime = function (timestamp, type) {
var date = new Date(timestamp * 1000) // 时间戳为10位需*1000时间戳为13位的话不需乘1000
var Y = date.getFullYear()
var M =
date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var dateStr = ''
switch (type) {
case 1:
dateStr = Y + '年' + M + '月' + D + '日'
break
case 2:
dateStr = Y + '-' + M + '-' + D
break
default:
dateStr = Y + '年' + M + '月' + D + '日'
}
return dateStr
}
// 标准化时间 即将 2015年12月31日 转为 2015-12-31
const dateFormat = function (dateStr) {
if (dateStr) {
dateStr = dateStr.replace('年', '-')
dateStr = dateStr.replace('月', '-')
dateStr = dateStr.replace('日', '')
return dateStr
} else {
return ''
}
}
// 存储本地浏览器 mainKey是唯一标识 aryy是存储书 type - save 是存 getdata是取
const saveactionDate = function (mainKey, arry, type) {
const _this = this
if (arry) {
arry.forEach(item => {
if (type === 'save') {
// 保存操作
window.localStorage.setItem(mainKey + '-' + item, JSON.stringify(_this[item]))
} else {
// 回显
_this[item] = JSON.parse(window.localStorage.getItem(mainKey + '-' + item) ? window.localStorage
.getItem(mainKey + '-' + item) : [])
}
})
}
}
export {
formatDate,
timestampToTime,
dateFormat,
saveactionDate
};

158
src/utils/validate.js Normal file
View File

@@ -0,0 +1,158 @@
/**
* 验证是否为空
* @param string|array value
* @returns
*/
function isEmpty(value) {
if (value === null || value === undefined || value === "") {
return true;
}
if (Array.isArray(value) && value.length === 0) {
return true;
}
return false;
}
/**
* 是否为手机号
* @param {*} value
* @param {*} param1
* @returns
*/
export const mobileValidator = (value, [locale]) => {
if (isEmpty(value)) {
return true;
}
if ((!locale || locale == "CN") && /^1[3456789][0-9]{9}$/.test(value)) {
return true;
} else if (locale == "EN" && /^\+[\d]{1,5}\s[\d]{1,14}$/.test(value)) {
return true;
}
return "请输入正确的手机号";
};
/**
* 是否为电话号码
* @param value
* @param {*} param1
* @returns
*/
export const telValidator = (value, [locale]) => {
if (isEmpty(value)) {
return true;
}
if ((!locale || locale == "CN") && !/^(?:0|8)[1-9]{3,}-[0-9]{8}$/.test(value)) {
return true;
}
return "电话号码格式不正确";
};
/**
* 身份证号码是否正确
* @param string value
* @returns
*/
export const identifyValidator = (value) => {
if (isEmpty(value)) {
return true;
}
if (!/(?:^\d{15}$)|(?:^\d{18}$)|(?:^\d{17}(?:\d|X|x)$)/.test(value)) {
return "身份证号码格式不正确";
}
return true;
};
/**
* 验证小数位长度
* @param number value 值
* @param number param1.length 为小数位长度
* @returns
*/
export const decimalValidator = (value, [length]) => {
if (isEmpty(value)) {
return true;
}
let regExp = new RegExp("^[0-9]+(?:.[0-9])?$");
if (length) {
regExp = new RegExp("^[0-9]+(?:.[0-9]{1," + length + "})?$");
}
if (regExp.test(value)) {
return true;
}
return "小数位长度不正确";
};
/**
* 验证是否为大写字母
* @param string value
* @returns
*/
export const letterUpperValidator = (value) => {
if (isEmpty(value) || /^[A-Z]+$/.test(value)) {
return true;
}
return "请填写大写字母";
};
/**
* 验证是否为小写字母
* @param string value
* @returns
*/
export const letterLowerValidator = (value) => {
if (isEmpty(value) || /^[a-z]+$/.test(value)) {
return true;
}
return "请填写小写字母";
};
/**
* 验证是否为中文
* @param string value
* @returns
*/
export const characterCNValidator = (value) => {
if (isEmpty(value) || /^[\u4e00-\u9fa5]+$/.test(value)) {
return true;
}
return "请输入中文";
};
/**
* 验证是否为邮编格式
* @param string value
* @returns
*/
export const zipcodeValidator = (value) => {
if (isEmpty(value) || /^[1-9]\d{5}(?!\d)$/.test(value)) {
return true;
}
return "请输入正确邮编";
};
/**
* 验证是否为传真格式
* @param string value
* @returns
*/
export const faxValidator = (value) => {
if (isEmpty(value) || /^(\d{3,4}-)?\d{7,8}$/.test(value)) {
return true;
}
return "请输入正确的传真格式";
};
const allValid = {
mobile: mobileValidator,
tel: telValidator,
identify: identifyValidator,
decimal: decimalValidator,
letter_upper: letterUpperValidator,
letter_lower: letterLowerValidator,
character_cn: characterCNValidator,
zipcode: zipcodeValidator,
fax: faxValidator
};
export default allValid;

335
src/views/PIP/copyright.vue Normal file
View File

@@ -0,0 +1,335 @@
<template>
<main class="m-20">
<div class="wrap text-black">
<!--顶部搜索-->
<el-row class="bg_white searchBox">
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="100px" class="m-t-20">
<el-row>
<el-col :span="6">
<el-form-item label="版权名称" prop="">
<el-input v-model="filter.name" style="width: 60%;" placeholder="请输入版权名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="版权类型" prop="">
<el-select v-model="filter.copyright_type_id" placeholder="请选择版权类型" @change="change_copyright">
<el-option v-for="(item, index) in copyRight" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="紧急程度" prop="">
<el-select v-model="filter.urgency_degree" placeholder="请选择紧急程度" @change="change_urgency">
<el-option v-for="(item, index) in urgency" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4" :offset="2">
<el-button type="primary" @click="searchClick">搜索</el-button>
<el-button type="primary" @click="reset">重置</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<!--table-->
<el-row class="bg_white m-t-20">
<el-col :span=24>
<el-row class="m-t-20">
<el-col :span="6" class="m-l-40">
<el-button type="primary" @click="addClick">新增版权</el-button>
<el-button type="primary" @click="downloadTemplate('')">下载装备材料模板</el-button>
</el-col>
</el-row>
<el-table class="m-20" :data="tableData" style="width: auto;" border :header-cell-style="header_style">
<el-table-column fixed prop="id" label="编码" width="80" align="center" />
<el-table-column fixed prop="name" label="版权名称" width="180">
<template #default="scope">
<span @click="editClick(scope.row)" class="text_blue Cursor">{{scope.row.name}}</span>
</template>
</el-table-column>
<el-table-column prop="copyright_type_id" label="版权类型" width="180" />
<el-table-column prop="urgency_degree" label="紧急程度" />
<template v-if="this.isCopyright">
<el-table-column prop="" label="申请表" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.apply_file)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="源程序代码" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.code)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="说明书" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.instructions)">下载</span>
</template>
</el-table-column>
</template>
<template v-else>
<el-table-column prop="" label="作品说明表" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.art_dscription_form)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="法人作品说明" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.art_corporation_statement)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="作品等级申请表" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.art_level_form)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="作品样本" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.demo)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="作品登记委托书" width="100" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.art_sign_file)">下载</span>
</template>
</el-table-column>
</template>
<el-table-column prop="apply_result" label="申请结果" width="180" />
<el-table-column prop="price" label="单价(¥)" align="center" />
<el-table-column prop="num" label="数量" align="center" />
<el-table-column prop="total_price" label="总计(¥)" align="center" />
<el-table-column prop="" label="操作" width="180" align="center">
<template #default="scope">
<span @click="editClick(scope.row)" class="text_blue Cursor m-r-10">查看详情</span>
<span @click="deleteClick(scope.row, scope.$index)" class="text_blue Cursor">删除</span>
</template>
</el-table-column>
</el-table>
<el-row class=" p-20">
<el-pagination
class="pagination"
v-model="currentPage"
:page-size="filter.size"
layout="total, prev, pager, next"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</main>
</template>
<script>
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: 'copyRight',
data() {
return {
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
form: {},
copyRight: [],
urgency: [],
tableData: [],
currentPage: 1,
total: 0,
filter: {
page: 1,
size: 10,
name: '',
urgency_degree: '',
copyright_type_id: 1
},
url: '',
name: '',
isCopyright: true
}
},
created() {
this.getData()
this.getUrl()
},
activated() {
this.getList()
},
methods: {
// 版权类型
change_copyright(val) {
this.filter.copyright_type_id = val
if (this.filter.copyright_type_id == 1) {
this.isCopyright = true
} else {
this.isCopyright = false
}
this.filter.page = 1
this.filter.size = 10
this.getList()
},
// 紧急程度
change_urgency(val) {
this.filter.urgency_degree = val
},
//搜索
searchClick() {
if (this.filter.copyright_type_id == 1) {
this.isCopyright = true
} else {
this.isCopyright = false
}
this.filter.page = 1
this.filter.size = 10
this.getList()
},
// 重置
reset() {
this.filter = {
page: 1,
size: 10,
name: '',
urgency_degree: '',
copyright_type_id: 1
}
this.isCopyright = true
this.getList()
},
// 获取下载链接
getUrl() {
this.$http.get('copyright/copyrightTemplate').then(res => {
if(res.status == 200) {
this.url = res.data.data.url
this.name = res.data.data.name
}
})
},
// 获取基础数据
getData() {
this.$http.get('copyright/constList').then(res => {
if (res.status == 200) {
this.copyRight = res.data.data.copyright_type_id
this.urgency = res.data.data.urgency_degree
}
})
},
//版权list
getList() {
this.$http.get('copyright/index', this.filter).then(res => {
if (res.status == 200 ) {
this.tableData = res.data.data.data
this.total = res.data.data.count
}
})
},
// 改变每页请求条数
changePageSize(size) {
this.filter.size = size;
this.getList();
},
// 翻页
changePage(page) {
this.filter.page = page;
this.getList();
},
// 新增商标
addClick() {
this.$router.push({
path: '/PIP/copyright_add'
})
},
// 编辑
editClick(row) {
console.log(row)
let type_id = ''
if (row.copyright_type_id == '软著登记') {
type_id = 1
} else {
type_id = 2
}
this.$router.push({
path: '/PIP/copyright_edit',
query: {
id: row.id,
type_id: type_id
}
})
},
// 删除
deleteClick(row, index) {
ElMessageBox.confirm('确认删除该专利?', '提示', {
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.delete('copyright/delete/id?id=' + row.id ).then(res => {
if (res.status == 200) {
this.getList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
// 下载模板
downloadTemplate(data) {
this.$message({
type: 'success',
message: '正在下载,请稍后...'
})
let url = ''
if (data == '') {
url = this.url
} else {
url = data
}
axios.get(url, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
}).then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const url_arr = res.config.url.split('/')
const nameStr = decodeURI(url_arr[url_arr.length - 1])
console.log(nameStr)
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
}
}
}
</script>
<style scoped>
.wrap{ width: auto;}
</style>

View File

@@ -0,0 +1,701 @@
<template>
<main>
<div class="bg_white m-20" style="margin-bottom: 70px;">
<div class="wrap text-black p-t-20 p-b-20 p-l-40 p-r-40">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" class="m-t-20" label-position="left">
<div class="basic_info">
<h3>基础信息</h3>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="编码" prop="" required>
<el-input v-model="form.id" style="width: 60%;" disabled="true" placeholder="保存时自动生成"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="版权类型" prop="copyright_type_id">
<el-select v-model="form.copyright_type_id" placeholder="请选择版权类型" @change="changeCopyrightType">
<el-option v-for="(item, index) in copyrightType" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" style="width: 60%;" placeholder="请输入名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="紧急程度" prop="urgency_degree">
<el-select v-model="form.urgency_degree" placeholder="请选择紧急程度" @change="changeUrgencyDegree">
<el-option v-for="(item, index) in urgencyDegree" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="others">
<h3>附件上传</h3>
<el-row v-if="type_id == 1">
<el-col :span="8">
<el-form-item label="申请表" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="fileUpload"
:limit="1"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="源程序代码" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess1"
:on-preview="handlePreview1"
:on-remove="handleRemove1"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed1"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList1"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="说明书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess2"
:on-preview="handlePreview2"
:on-remove="handleRemove2"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed2"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList2"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
</el-row>
<el-row v-else>
<el-col :span="8">
<el-form-item label="作品说明书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess3"
:on-preview="handlePreview3"
:on-remove="handleRemove3"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed3"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList3"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="法人作品声明" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess4"
:on-preview="handlePreview4"
:on-remove="handleRemove4"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed4"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList4"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="作品等级申请表" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess5"
:on-preview="handlePreview5"
:on-remove="handleRemove5"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed5"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList5"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="作品登记委托书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess6"
:on-preview="handlePreview6"
:on-remove="handleRemove6"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed6"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList6"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="作品样本" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess7"
:on-preview="handlePreview7"
:on-remove="handleRemove7"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed7"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList7"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
<!-- <el-upload
ref="upload"
:action="api_upload_url"
list-type="picture-card"
name="img"
:with-credentials = "true"
:on-success="handlePhotoSuccess"
:on-preview="handlePhotoPreview"
multiple
:limit="4"
:on-remove="handlePhotoRemove"
accept=".jpg,.png"
:on-exceed="handlePhotoExceed"
:file-list="imgList"
>
<el-button size="small" type="text"><i class="el-icon-plus"></i></el-button>
</el-upload>
<div class="el-upload__tip f_12 l_height_25">支持pngjpg格式, 上限1M, 不超过4张, 需彩色图片</div>
<el-dialog v-model="dialogVisible">
<el-image width="100%" :src="dialogImageUrl" alt=""></el-image>
</el-dialog> -->
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<h3>申请结果</h3>
<el-radio-group v-model="form.apply_result" @change="changeApply">
<el-radio v-for="(item, index) in checkData" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<h3>费用信息</h3>
<el-row>
<el-col :span="8">
<el-form-item label="单价" prop="">
<el-input v-model="form.price" style="width: 60%;" placeholder="仅限数字,支持小数" @change="changePrice"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="">
<el-input v-model="form.num" style="width: 60%;" placeholder="仅限正整数" @change="changeNum"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总计" prop="">
<el-input v-model="form.total_price" style="width: 60%;" placeholder="自动计算" disabled="true"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</div>
<div class="bg_white m-t-10 p-l-20 p-r-20 p-t-10 p-b-10 text-black footer" style="width:100%;">
<el-button type="primary" class="search_button" @click="submitClick('form')">提交</el-button>
</div>
</main>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
form: {
id: '',
copyright_type_id: 1,
name: '',
urgency_degree: ''
},
rules: {
name: [
{
required: true,
message: '请输入版权名称',
trigger: 'blur',
}
],
copyright_type_id: [
{
required: true,
message: '请选择版权类型',
trigger: 'change',
}
],
urgency_degree: [
{
required: true,
message: '请选择紧急程度',
trigger: 'change',
}
]
},
fileList: [],
fileList1: [],
fileList2: [],
fileList3: [],
fileList4: [],
fileList5: [],
fileList6: [],
fileList7: [],
imgList: [],
dialogVisible: false,
dialogImageUrl: '',
copyrightType: [],
urgencyDegree: [],
checkData: [],
isShowDemo: false,
type_id: 1,
edit_params: {
name: '',
copyright_type_id: 1,
urgency_degree: '',
apply_file: '',
code: '',
instructions: '',
demo: '',
apply_result: '',
price: 0,
num: 0,
total_price: 0,
art_dscription_form: '',
art_corporation_statement: '',
art_level_form: '',
art_sign_file: ''
},
imgData: [],
curPath: ''
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + 'admin/copyright/upload'
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags
})
},
created() {
this.getList()
this.curPath = this.$route.path
},
activated() {
},
beforeRouteLeave(to,from,next) {
const toPath = to.path
let flag = false
this.tags.forEach(cur => {
if (cur.path != this.curPath) {
flag = true
} else {
flag = false
}
})
if (flag == true) {
this.resetData()
}
next()
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
// 获取列表数据
getList() {
this.$http.get('copyright/constList').then(res => {
console.log(res)
const data = res.data.data
this.copyrightType = data.copyright_type_id
this.urgencyDegree = data.urgency_degree
this.checkData = data.apply_result
})
},
// 限制文件格式
fileUpload(file) {
console.log(file)
const isLt5M = file.size / 1024 / 1024 < 10
if (!isLt5M) {
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
return false
}
// 文件格式拦截
const fileType = file.type
if (fileType != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' && fileType != 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' &&
fileType != 'application/pdf' && fileType != 'application/msword') {
this.$message({
message: '上传失败,当前文件格式无法上传!',
type: 'warning'
})
return false
}
},
//文件上传成功时
handleSuccess(res, file, file_list) {
console.log(res)
if (res.status == 200) {
this.edit_params.apply_file = res.data.data.url
}
},
handleRemove(file, fileList) {
this.edit_params.apply_file = ''
},
//文件上传成功时1
handleSuccess1(res, file, file_list) {
if (res.status == 200) {
this.edit_params.code = res.data.data.url
}
},
handleRemove1(file, fileList) {
this.edit_params.code = ''
},
//文件上传成功时2
handleSuccess2(res, file, file_list) {
if (res.status == 200) {
this.edit_params.instructions = res.data.data.url
}
},
handleRemove2(file, fileList) {
this.edit_params.instructions = ''
},
//文件上传成功时3
handleSuccess3(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_dscription_form = res.data.data.url
}
},
handleRemove3(file, fileList) {
this.edit_params.art_dscription_form = ''
},
//文件上传成功时4
handleSuccess4(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_corporation_statement = res.data.data.url
}
},
handleRemove4(file, fileList) {
this.edit_params.art_corporation_statement = ''
},
//文件上传成功时5
handleSuccess5(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_level_form = res.data.data.url
}
},
handleRemove5(file, fileList) {
this.edit_params.art_level_form = ''
},
//文件上传成功时6
handleSuccess6(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_sign_file = res.data.data.url
}
},
handleRemove6(file, fileList) {
this.edit_params.art_sign_file = ''
},
//文件上传成功时6
handleSuccess7(res, file, file_list) {
if (res.status == 200) {
this.edit_params.demo = res.data.data.url
}
},
handleRemove7(file, fileList) {
this.edit_params.demo = ''
},
//图片上传成功时
handlePhotoSuccess(res, file, file_list) {
if (res.status == 200) {
this.imgData.push(res.data.data.url)
}
this.edit_params.demo = this.imgData.join(',')
},
//点击文件列表中已上传的文件时
handlePhotoPreview(file) {},
//文件列表移除
handlePhotoRemove(file, fileList) {
this.edit_params.demo = ''
},
//文件超出个数限制
handlePhotoExceed(files, fileList) {
const fileLen = files.length
const listLen = fileList.length + fileLen
if (fileLen > 4 || listLen > 4) {
this.$message({
message: '只能上传4张作品样本!',
type: 'warning'
})
return false
}
},
// 版权类型
changeCopyrightType(val) {
this.type_id = val
this.edit_params.copyright_type_id = val
},
// 紧急程度
changeUrgencyDegree(val) {
this.edit_params.urgency_degree = val
},
// 申请结果
changeApply(val) {
this.edit_params.apply_result = val
},
// 修改价格
changePrice(val) {
this.form.price = val
this.edit_params.price = val
this.calculation(val, this.edit_params.num)
},
// 修改数量
changeNum(val) {
this.form.num = val
this.edit_params.num = val
this.calculation(this.edit_params.price, val)
},
// 计算合计费用
calculation(price, num) {
price = Number(price)
num = Number(num)
let total_price = 0
total_price = (price*num).toFixed(2)
this.form.total_price = total_price
this.edit_params.total_price = total_price
},
//提交
submitClick(form) {
this.edit_params.name = this.form.name
if (this.edit_params.copyright_type_id == 1) {
if (this.edit_params.apply_file == '') {
this.$message({
type: 'error',
message: '请上传申请表'
})
return false
}
if (this.edit_params.code == '') {
this.$message({
type: 'error',
message: '请上传源程序代码'
})
return false
}
if (this.edit_params.instructions == '') {
this.$message({
type: 'error',
message: '请上传说明书'
})
return false
}
} else {
if (this.edit_params.art_dscription_form == '') {
this.$message({
type: 'error',
message: '请上传作品说明书'
})
return false
}
if (this.edit_params.art_corporation_statement == '') {
this.$message({
type: 'error',
message: '请上传法人作品声明'
})
return false
}
if (this.edit_params.art_level_form == '') {
this.$message({
type: 'error',
message: '请上传作品等级申请表'
})
return false
}
if (this.edit_params.art_sign_file == '') {
this.$message({
type: 'error',
message: '请上传作品登记委托书'
})
return false
}
if (this.edit_params.demo == '') {
this.$message({
type: 'error',
message: '请上传作品样本'
})
return false
}
}
console.log(this.edit_params)
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message({
type: 'error',
message: '信息填写不完整!'
})
return false
} else {
this.$http.post('copyright/save', this.edit_params ).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.resetData()
this.imgList = []
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/PIP/copyright'
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
})
},
resetData() {
this.fileList = []
this.fileList1 = []
this.fileList2 = []
this.fileList3 = []
this.fileList4 = []
this.fileList5 = []
this.fileList6 = []
this.fileList7 = []
this.form = {
name: '',
copyright_type_id: 1,
urgency_degree: '',
apply_file: '',
code: '',
instructions: '',
demo: '',
apply_result: '',
price: '',
num: '',
total_price: '',
}
this.edit_params = {
name: '',
copyright_type_id: 1,
urgency_degree: '',
apply_file: '',
code: '',
instructions: '',
demo: '',
apply_result: '',
price: 0,
num: 0,
total_price: 0,
}
}
}
}
</script>
<style scoped>
.basic_info{ border-bottom: 1px solid #dcdfe6;}
</style>

View File

@@ -0,0 +1,745 @@
<template>
<main>
<div class="bg_white m-20" style="margin-bottom: 70px;">
<div class="wrap text-black p-t-20 p-b-20 p-l-40 p-r-40">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" class="m-t-20" label-position="left">
<div class="basic_info">
<h3>基础信息</h3>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="编码" prop="" required>
<el-input v-model="form.id" style="width: 60%;" disabled="true" placeholder=""></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="版权类型" prop="copyright_type_id">
<el-select v-model="form.copyright_type_id" placeholder="请选择版权类型" disabled="true" @change="changeCopyrightType">
<el-option v-for="(item, index) in copyrightType" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" style="width: 60%;" placeholder="请输入名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="紧急程度" prop="urgency_degree">
<el-select v-model="form.urgency_degree" placeholder="请选择紧急程度" @change="changeUrgencyDegree">
<el-option v-for="(item, index) in urgencyDegree" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="others">
<h3>附件上传</h3>
<el-row v-if="type_id == 1">
<el-col :span="8">
<el-form-item label="申请表" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="fileUpload"
:limit="1"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="源程序代码" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess1"
:on-preview="handlePreview1"
:on-remove="handleRemove1"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed1"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList1"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="说明书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess2"
:on-preview="handlePreview2"
:on-remove="handleRemove2"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed2"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList2"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
</el-row>
<el-row v-else>
<el-col :span="8">
<el-form-item label="作品说明书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess3"
:on-preview="handlePreview3"
:on-remove="handleRemove3"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed3"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList3"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="法人作品声明" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess4"
:on-preview="handlePreview4"
:on-remove="handleRemove4"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed4"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList4"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="作品等级申请表" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess5"
:on-preview="handlePreview5"
:on-remove="handleRemove5"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed5"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList5"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="作品登记委托书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess6"
:on-preview="handlePreview6"
:on-remove="handleRemove6"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed6"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList6"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="作品样本" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess7"
:on-preview="handlePreview7"
:on-remove="handleRemove7"
:before-upload="fileUpload"
:limit="1"
:on-exceed="handleExceed7"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList7"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
<!-- <el-upload
ref="upload"
:action="api_upload_url"
list-type="picture-card"
name="img"
:with-credentials = "true"
:on-success="handlePhotoSuccess"
:on-preview="handlePhotoPreview"
multiple
:limit="4"
:on-remove="handlePhotoRemove"
accept=".jpg,.png"
:on-exceed="handlePhotoExceed"
:file-list="imgList"
>
<el-button size="small" type="text"><i class="el-icon-plus"></i></el-button>
</el-upload>
<div class="el-upload__tip f_12 l_height_25">支持pngjpg格式, 上限1M, 不超过4张, 需彩色图片</div>
<el-dialog v-model="dialogVisible">
<el-image width="100%" :src="dialogImageUrl" alt=""></el-image>
</el-dialog> -->
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<h3>申请结果</h3>
<el-radio-group v-model="form.apply_result" @change="changeApply">
<el-radio v-for="(item, index) in checkData" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<h3>费用信息</h3>
<el-row>
<el-col :span="8">
<el-form-item label="单价" prop="">
<el-input v-model="form.price" style="width: 60%;" placeholder="仅限数字,支持小数" @change="changePrice"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="">
<el-input v-model="form.num" style="width: 60%;" placeholder="仅限正整数" @change="changeNum"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总计" prop="">
<el-input v-model="form.total_price" style="width: 60%;" placeholder="" disabled="true"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</div>
<div class="bg_white m-t-10 p-l-20 p-r-20 p-t-10 p-b-10 text-black footer" style="width:100%;">
<el-button type="primary" class="search_button" @click="submitClick('form')">提交</el-button>
</div>
</main>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
form: {
id: '',
copyright_type_id: 1,
name: '',
urgency_degree: ''
},
rules: {
name: [
{
required: true,
message: '请输入版权名称',
trigger: 'blur',
}
],
copyright_type_id: [
{
required: true,
message: '请选择版权类型',
trigger: 'change',
}
],
urgency_degree: [
{
required: true,
message: '请选择紧急程度',
trigger: 'change',
}
]
},
fileList: [],
fileList1: [],
fileList2: [],
imgList: [],
fileList3: [],
fileList4: [],
fileList5: [],
fileList6: [],
fileList7: [],
dialogVisible: false,
dialogImageUrl: '',
copyrightType: [],
urgencyDegree: [],
checkData: [],
isShowDemo: false,
type_id: 1,
edit_params: {
name: '',
copyright_type_id: '',
urgency_degree: '',
apply_file: '',
code: '',
instructions: '',
demo: '',
apply_result: '',
price: '',
num: '',
total_price: '',
art_dscription_form: '',
art_corporation_statement: '',
art_level_form: '',
art_sign_file: ''
},
imgData: []
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + 'admin/copyright/upload'
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags
})
},
created() {
this.getList()
},
activated() {
this.id = this.$route.query.id
this.type_id = this.$route.query.type_id
this.getDetail()
},
beforeRouteUpdate(to,from,next){
this.id = to.query.id
if(to.fullPath!=from.fullPath){
this.getDetail()
next()
}
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
// 获取列表数据
getList() {
this.$http.get('copyright/constList').then(res => {
console.log(res)
const data = res.data.data
this.copyrightType = data.copyright_type_id
this.urgencyDegree = data.urgency_degree
this.checkData = data.apply_result
})
},
getDetail() {
this.$http.get('copyright/read/id', { id: this.id }).then(res => {
console.log(res)
this.imgList = []
if (res.status == 200) {
this.form = res.data.data
if(this.form.apply_file != null && this.form.apply_file != '') {this.fileList = [{name: '申请表', url: this.form.apply_file}]}
if(this.form.code != null && this.form.code != '') {this.fileList1 = [{name: '程序源代码', url: this.form.code}]}
if(this.form.instructions != null && this.form.instructions != '') {this.fileList2 = [{name: '说明书', url: this.form.instructions}]}
if(this.form.art_dscription_form != null && this.form.art_dscription_form != '') {this.fileList3 = [{name: '作品说明书', url: this.form.art_dscription_form}]}
if(this.form.art_corporation_statement != null && this.form.art_corporation_statement != '') {this.fileList4 = [{name: '法人作品声明', url: this.form.art_corporation_statement}]}
if(this.form.art_level_form != null && this.form.art_level_form != '') {this.fileList5 = [{name: '作品等级申请表', url: this.form.art_level_form}]}
if(this.form.art_sign_file != null && this.form.art_sign_file != '') {this.fileList6 = [{name: '作品等级委托书', url: this.form.art_sign_file}]}
if(this.form.demo != null && this.form.demo != '') {
this.fileList7 = [{name: '作品样本', url: this.form.demo}]
// const demo = this.form.demo.split(',')
// demo.forEach(item => {
// this.imgList.push({name: '', url: item})
// });
}
// 字符转数字类型
this.form.apply_result = Number(this.form.apply_result)
// 未做修改直接保存
this.edit_params = {
id: this.form.id,
name: this.form.name,
copyright_type_id: this.form.copyright_type_id,
urgency_degree: this.form.urgency_degree,
apply_file: this.form.apply_file,
code: this.form.code,
instructions: this.form.instructions,
demo: this.form.demo,
apply_result: this.form.apply_result,
price: this.form.price,
num: this.form.num,
total_price: this.form.total_price,
art_dscription_form: this.form.art_dscription_form,
art_corporation_statement: this.form.art_corporation_statement,
art_level_form: this.form.art_level_form,
art_sign_file: this.form.art_sign_file
}
}
})
},
//文件上传成功时
handleSuccess(res, file, file_list) {
console.log(res)
if (res.status == 200) {
this.edit_params.apply_file = res.data.data.url
}
},
// 限制文件格式
fileUpload(file) {
console.log(file)
const isLt5M = file.size / 1024 / 1024 < 10
if (!isLt5M) {
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
return false
}
// 文件格式拦截
const fileType = file.type
if (fileType != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' && fileType != 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' &&
fileType != 'application/pdf' && fileType != 'application/msword') {
this.$message({
message: '上传失败,当前文件格式无法上传!',
type: 'warning'
})
return false
}
},
handleRemove(file, fileList) {
this.edit_params.apply_file = ''
},
//文件上传成功时1
handleSuccess1(res, file, file_list) {
if (res.status == 200) {
this.edit_params.code = res.data.data.url
}
},
handleRemove1(file, fileList) {
this.edit_params.code = ''
},
//文件上传成功时2
handleSuccess2(res, file, file_list) {
if (res.status == 200) {
this.edit_params.instructions = res.data.data.url
}
},
handleRemove2(file, fileList) {
this.edit_params.instructions = ''
},
//文件上传成功时3
handleSuccess3(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_dscription_form = res.data.data.url
}
},
handleRemove3(file, fileList) {
this.edit_params.art_dscription_form = ''
},
//文件上传成功时4
handleSuccess4(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_corporation_statement = res.data.data.url
}
},
handleRemove4(file, fileList) {
this.edit_params.art_corporation_statement = ''
},
//文件上传成功时5
handleSuccess5(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_level_form = res.data.data.url
}
},
handleRemove5(file, fileList) {
this.edit_params.art_level_form = ''
},
//文件上传成功时6
handleSuccess6(res, file, file_list) {
if (res.status == 200) {
this.edit_params.art_sign_file = res.data.data.url
}
},
handleRemove6(file, fileList) {
this.edit_params.art_sign_file = ''
},
//文件上传成功时6
handleSuccess7(res, file, file_list) {
if (res.status == 200) {
this.edit_params.demo = res.data.data.url
}
},
handleRemove7(file, fileList) {
this.edit_params.demo = ''
},
//图片上传成功时
handlePhotoSuccess(res, file, fileList) {
console.log(fileList, 111)
this.edit_params.demo = ''
this.imgData = []
fileList.forEach(item => {
if (item.response) {
this.imgData.push(item.response.data.data.url)
} else {
this.imgData.push(item.url)
}
})
console.log(this.imgData, 2222)
this.edit_params.demo = this.imgData.join(',')
},
//点击文件列表中已上传的文件时
handlePhotoPreview(file) {},
//文件列表移除
handlePhotoRemove(file, fileList) {
console.log(file, fileList)
this.edit_params.demo = ''
let imgs = []
this.imgList = []
// this.imgData = []
fileList.forEach(item => {
imgs.push(item.url)
this.imgList.push({name: '', url: item.url})
})
console.log(imgs)
// if (this.imgList.length != 0) {
// this.imgList.forEach(item => {
// this.imgData.push(item.url)
// })
// }
this.edit_params.demo = imgs.join(',')
},
//文件超出个数限制
handlePhotoExceed(files, fileList) {
const fileLen = files.length
const listLen = fileList.length + fileLen
if (fileLen > 4 || listLen > 4) {
this.$message({
message: '只能上传4张作品样本!',
type: 'warning'
})
return false
}
},
// 版权类型
changeCopyrightType(val) {
this.type_id = val
this.edit_params.copyright_type_id = val
if (val == 1) {
this.fileList3 = []
this.fileList4 = []
this.fileList5 = []
this.fileList6 = []
this.fileList7 = []
this.imgList = []
} else {
this.fileList = []
this.fileList1 = []
this.fileList2 = []
}
},
// 紧急程度
changeUrgencyDegree(val) {
this.edit_params.urgency_degree = val
},
// 申请结果
changeApply(val) {
this.edit_params.apply_result = val
},
// 修改价格
changePrice(val) {
this.form.price = val
this.edit_params.price = val
this.calculation(val, this.edit_params.num)
},
// 修改数量
changeNum(val) {
this.form.num = val
this.edit_params.num = val
this.calculation(this.edit_params.price, val)
},
// 计算合计费用
calculation(price, num) {
price = Number(price)
num = Number(num)
let total_price = 0
total_price = (price*num).toFixed(2)
this.form.total_price = total_price
this.edit_params.total_price = total_price
},
//提交
submitClick(form) {
this.edit_params.name = this.form.name
console.log(this.edit_params)
if (this.edit_params.copyright_type_id == 1) {
if (this.edit_params.apply_file == '') {
this.$message({
type: 'error',
message: '请上传申请表'
})
return false
}
if (this.edit_params.code == '') {
this.$message({
type: 'error',
message: '请上传源程序代码'
})
return false
}
if (this.edit_params.instructions == '') {
this.$message({
type: 'error',
message: '请上传说明书'
})
return false
}
} else {
if (this.edit_params.art_dscription_form == '') {
this.$message({
type: 'error',
message: '请上传作品说明书'
})
return false
}
if (this.edit_params.art_corporation_statement == '') {
this.$message({
type: 'error',
message: '请上传法人作品声明'
})
return false
}
if (this.edit_params.art_level_form == '') {
this.$message({
type: 'error',
message: '请上传作品等级申请表'
})
return false
}
if (this.edit_params.art_sign_file == '') {
this.$message({
type: 'error',
message: '请上传作品登记委托书'
})
return false
}
if (this.edit_params.demo == '') {
this.$message({
type: 'error',
message: '请上传作品样本'
})
return false
}
}
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message({
type: 'error',
message: '信息填写不完整!'
})
return false
} else {
this.$http.put('copyright/update/id', this.edit_params ).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.getDetail()
this.fileList = []
this.fileList1 = []
this.fileList2 = []
this.fileList3 = []
this.fileList4 = []
this.fileList5 = []
this.fileList6 = []
this.fileList7 = []
this.imgList = []
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/PIP/copyright'
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
})
}
}
}
</script>
<style scoped>
.basic_info{ border-bottom: 1px solid #dcdfe6;}
</style>

421
src/views/PIP/patent.vue Normal file
View File

@@ -0,0 +1,421 @@
<template>
<main class="m-20">
<div class="wrap text-black">
<!--顶部搜索-->
<el-row class="bg_white searchBox">
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="100px" class="m-t-20">
<el-row>
<el-col :span="6">
<el-form-item label="名称" prop="">
<el-input v-model="filter.name" style="width: 220px;" placeholder="请输入专利名称/公司名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="专利类型" prop="">
<el-select v-model="filter.patent_type" placeholder="请选择专利类型">
<el-option v-for="(item, index) in patentType" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="公告时间" prop="">
<el-date-picker
v-model="filter.publish_time"
type="date"
placeholder="请选择公告时间"
value-format="YYYY-MM-DD"
@change="changePublishTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="续费时间" prop="">
<el-date-picker
v-model="filter.renewals_time"
type="date"
placeholder="请选择续费时间"
value-format="YYYY-MM-DD"
@change="changeRenewalsTime">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="项目负责人" prop="">
<el-cascader
v-model="depts"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept"
>
</el-cascader>
<el-select v-model="admin_ids" placeholder="请选择项目负责人" @change="selLeader">
<el-option v-for="(item, index) in adminData" :key="index" :label="item.staff_name" :value="item.staff_code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" :offset="1">
<el-form-item label="申请人" prop="">
<el-cascader
v-model="admins"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept1"
>
</el-cascader>
<el-select v-model="apply_man" placeholder="请选择申请人" @change="changeAdmin">
<el-option v-for="(item, index) in adminData1" :key="index" :label="item.staff_name" :value="item.staff_code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4" :offset="3">
<el-button type="primary" @click="searchClick">搜索</el-button>
<el-button type="primary" @click="reset">重置</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<!--table-->
<el-row class="bg_white m-t-20">
<el-col :span="24">
<el-row class="m-t-20">
<el-col :span="6" class="m-l-40">
<el-button type="primary" @click="addClick">新增专利</el-button>
<el-button class="m-l-10" type="primary" @click="downloadTemplate('')">下载专利交底模板</el-button>
</el-col>
</el-row>
<el-table class="m-20" :data="tableData" style="width: auto;" border :header-cell-style="header_style">
<el-table-column fixed prop="id" label="编码" width="80" align="center" />
<el-table-column fixed prop="name" label="专利名称(型号)" width="180">
<template #default="scope">
<span @click="editClick(scope.row)" class="text_blue Cursor">{{scope.row.name}}</span>
</template>
</el-table-column>
<el-table-column prop="patent_type_id" label="专利类型" width="120" />
<el-table-column prop="admin_ids" label="项目负责人" width="180" />
<el-table-column prop="progress" label="申请进度" />
<el-table-column prop="is_outcountry" label="是否涉及国外" width="120" align="center" />
<el-table-column prop="worth_level" label="价值级别" width="100" align="center" />
<el-table-column prop="org_ids" label="申请主体" />
<el-table-column prop="apply_country" label="申请国家" width="100" align="center" />
<el-table-column prop="" label="技术交底" align="center">
<template #default="scope">
<span class="text_blue Cursor" @click="downloadTemplate(scope.row.technical_disclosure)">下载</span>
</template>
</el-table-column>
<el-table-column prop="" label="产品图片" width="180" align="center">
<template #default="scope">
<el-image :src="scope.row.production_image" style="width:50px; height:50px"></el-image>
</template>
</el-table-column>
<el-table-column prop="production_desc" label="产品功能简介" width="180" />
<el-table-column prop="checkout_result" label="检索结果" width="180" />
<el-table-column prop="apply_result" label="申请结果" width="300" />
<el-table-column prop="apply_time" label="申请时间" width="120" />
<el-table-column prop="publish_time" label="公告时间" width="120" />
<el-table-column prop="renewals_time" label="续费时间" width="120" />
<el-table-column prop="price" label="单价(¥)" align="center" />
<el-table-column prop="num" label="数量" width="180" align="center" />
<el-table-column prop="total_price" label="总计(¥)" width="180" align="center" />
<el-table-column prop="" label="操作" width="180" align="center">
<template #default="scope">
<span @click="editClick(scope.row)" class="text_blue Cursor m-r-10">查看详情</span>
<span @click="deleteClick(scope.row, scope.$index)" class="text_blue Cursor">删除</span>
</template>
</el-table-column>
</el-table>
<el-row class=" p-20">
<el-pagination
class="pagination"
v-model="currentPage"
:page-size="filter.size"
layout="total, prev, pager, next"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</main>
</template>
<script>
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: 'patent',
data() {
return {
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
form: {
name: '',
leader: [],
progress: [],
applyTime: '',
bulletinTime: '',
renewalTime: ''
},
tableData: [],
currentPage: 1,
total: 0,
filter: {
page: 1,
size: 10,
name: '',
admin_ids: '',
apply_man: '',
patent_type: '',
publish_time: '',
renewals_time: ''
},
adminData: [],
progress: [],
patentType: [],
url: '',
name: '',
admin_ids: '',
apply_man: '',
depts: [],
admins: [],
deptData: [],
deptCodes: '',
deptCodes1: '',
adminData1: []
}
},
created() {
this.getListData()
this.getAdminData()
this.getUrl()
},
activated() {
this.getList()
},
methods: {
// 获取下载链接
getUrl() {
this.$http.get('patent/technicalDisclosureTemplate').then(res => {
if(res.status == 200) {
this.url = res.data.data.url
this.name = res.data.data.name
}
})
},
//选择负责人
changeDept(val) {
this.deptCodes = val
const dept_code = val[val.length - 1]
this.$http.get('brand/getUserListByDeptCode', { dept_code: dept_code }).then(res => {
if (res.status == 200) {
this.adminData = res.data.data
}
})
},
selLeader(val) {
let admin_ids = {dept: [], user: []}
admin_ids.dept = this.deptCodes
admin_ids.user.push(val)
this.filter.admin_ids = JSON.stringify(admin_ids)
},
//申请人
changeDept1(val) {
this.deptCodes1 = val
const dept_code = val[val.length - 1]
this.$http.get('brand/getUserListByDeptCode', { dept_code: dept_code }).then(res => {
if (res.status == 200) {
this.adminData1 = res.data.data
}
})
},
changeAdmin(val) {
let apply_ids = {dept: [], user: []}
apply_ids.dept = this.deptCodes1
apply_ids.user.push(val)
this.filter.apply_man = JSON.stringify(apply_ids)
},
//选择进度
selProgress(val) {
this.filter.progress = val
},
// 申请时间
changeApplyTime(val) {
console.log(val)
this.filter.apply_time = val
},
changePublishTime(val) {
this.filter.publish_time = val
},
changeRenewalsTime(val) {
this.filter.renewals_time = val
},
//搜索
searchClick() {
this.filter.page = 1
this.filter.size = 10
this.getList()
},
// 重置
reset() {
this.filter = {
page: 1,
size: 10,
name: '',
admin_ids: '',
apply_man: '',
progress: '',
apply_time: '',
publish_time: '',
renewals_time: ''
}
this.depts = []
this.admins = []
this.admin_ids = ''
this.apply_man = ''
this.getList()
},
// 获取列表数据
getListData() {
this.$http.get('patent/constList').then(res => {
if (res.status == 200) {
const data = res.data.data
this.progress = data.progress
this.patentType = data.patent_type_id
}
})
},
// 获取项目负责人数据
getAdminData() {
this.$http.get('patent/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData = res.data.data
}
})
},
//专利list
getList() {
this.$http.get('patent/index', this.filter).then(res => {
console.log(res)
if (res.status == 200 ) {
this.tableData = res.data.data.data
this.total = res.data.data.count
}
})
},
// 改变每页请求条数
changePageSize(size) {
this.filter.size = size;
this.getList();
},
// 翻页
changePage(page) {
this.filter.page = page;
this.getList();
},
// 新增商标
addClick() {
this.$router.push({
path: '/PIP/patent_add'
})
},
// 编辑
editClick(row) {
this.$router.push({
path: '/PIP/patent_edit',
query: {
id: row.id
}
})
},
// 删除
deleteClick(row, index) {
console.log(row, index)
ElMessageBox.confirm('确认删除该专利?', '提示', {
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.delete('patent/delete/id?id=' + row.id ).then(res => {
if (res.status == 200) {
this.getList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
// 下载模板
downloadTemplate(data) {
this.$message({
type: 'success',
message: '正在下载,请稍后...'
})
let url = ''
if (data == '') {
url = this.url
} else {
url = data
}
axios.get(url, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
}).then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const url_arr = res.config.url.split('/')
const nameStr = decodeURI(url_arr[url_arr.length - 1])
console.log(nameStr)
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
}
}
}
</script>
<style scoped>
.wrap{ width: auto;}
</style>

View File

@@ -0,0 +1,866 @@
<template>
<main>
<div class="bg_white m-20" style="margin-bottom: 70px;">
<div class="wrap text-black p-t-20 p-b-20 p-l-40 p-r-40">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" class="m-t-20" label-position="left">
<div class="basic_info">
<h3>基础信息</h3>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="编码" prop="" required>
<el-input v-model="form.id" style="width: 60%;" disabled="true" placeholder="保存时自动生成"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="专利名称" prop="name">
<el-input v-model="form.name" style="width: 60%;" placeholder="请输入产品名称及型号"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请进度" prop="progress">
<el-select v-model="form.progress" placeholder="请选择申请进度" @change="changeProgress">
<el-option v-for="(item, index) in progress" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="项目负责人" prop="" required>
<template v-for="(item, index) in adminIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择项目负责人" filterable @change="selAdmin">
<el-option v-for="(item1, index1) in item.adminData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addAdmin"></i>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="申请人" prop="" required>
<template v-for="(item, index) in applyIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData1"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept1"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择申请人" filterable @change="selApply">
<el-option v-for="(item1, index1) in item.applyData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick1(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addApply"></i>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="专利类型" prop="patent_type_id">
<el-select v-model="form.patent_type_id" placeholder="请选择专利类型" @change="changePatent">
<el-option v-for="(item, index) in patentType" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="价值级别" prop="worth_level">
<el-select v-model="form.worth_level" placeholder="请选择价值级别" @change="changeWorth">
<el-option v-for="(item, index) in worthLevel" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请主体" prop="org_ids">
<el-input v-model="form.org_ids" placeholder="请输入公司名称" style="width: 60%;" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="是否涉及国外" prop="is_outcountry">
<el-select v-model="form.is_outcountry" placeholder="请选择是否涉及国外" @change="changeArea">
<el-option label="否" value="0"></el-option>
<el-option label="是" value="1"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请国家" prop="apply_country">
<el-input v-model="form.apply_country" placeholder="多个国家间用“,”隔开" style="width: 60%;" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品简介" prop="production_desc">
<el-input maxlength="100" show-word-limit type="textarea" placeholder="请输入产品简介" v-model="form.production_desc" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="产品图片" prop="" required>
<el-upload
ref="upload"
:action="api_upload_url"
list-type="picture-card"
name="img"
:with-credentials = "true"
:on-success="handlePhotoSuccess"
:on-preview="handlePhotoPreview"
:limit="1"
:on-remove="handlePhotoRemove"
accept=".jpg,.png"
:on-exceed="handlePhotoExceed"
:file-list="imgList"
>
<el-button size="small" type="text"><i class="el-icon-plus"></i></el-button>
</el-upload>
<div class="el-upload__tip f_12 l_height_25">支持pngjpg格式, 上限1M</div>
<el-dialog v-model="dialogVisible">
<el-image width="100%" :src="dialogImageUrl" alt=""></el-image>
</el-dialog>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="技术交底书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:before-upload="fileUpload"
:limit="1"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:on-exceed="handleExceed"
:file-list="fileList"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="others">
<el-row>
<el-col :span="12">
<h3>查询结果</h3>
<el-radio-group v-model="form.checkout_result" @change="changeSearch">
<el-radio v-for="(item, index) in checkData" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<h3>申请结果</h3>
<el-radio-group v-model="form.apply_result" @change="changeApply">
<el-radio v-for="(item, index) in applyData" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<h3>时间进度</h3>
<el-row>
<el-col :span="8">
<el-form-item label="申请时间" prop="apply_time">
<el-date-picker
v-model="form.apply_time"
type="date"
placeholder="请选择申请时间"
value-format="YYYY-MM-DD"
@change="changeApplyTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="公告时间">
<el-date-picker
v-model="form.publish_time"
type="date"
placeholder="请选择公告时间"
value-format="YYYY-MM-DD"
@change="changePublishTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="续费时间">
<el-date-picker
v-model="form.renewals_time"
type="date"
placeholder="请选择续费时间"
value-format="YYYY-MM-DD"
@change="changeRenewalsTime">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<h3>费用信息</h3>
<el-row>
<el-col :span="8">
<el-form-item label="单价" prop="">
<el-input v-model="form.price" style="width: 60%;" placeholder="仅限数字,支持小数" @change="changePrice"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="">
<el-input v-model="form.num" style="width: 60%;" placeholder="仅限正整数" @change="changeNum"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总计" prop="">
<el-input v-model="form.total_price" style="width: 60%;" placeholder="自动计算" disabled="true"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</div>
<div class="bg_white m-t-10 p-l-20 p-r-20 p-t-10 p-b-10 text-black footer" style="width:100%;">
<el-button type="primary" class="search_button" @click="submitClick('form')">提交</el-button>
</div>
</main>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
id: '',
form: {
admin_ids: [],
apply_man: [],
apply_country: "",
apply_result: "",
apply_time: "",
checkout_result: "",
is_outcountry: '',
name: "",
num: 0,
org_ids: "",
patent_type_id: '',
price: 0,
production_desc: "",
production_image: "",
progress: '',
publish_time: "",
renewals_time: "",
technical_disclosure: "",
total_price: 0,
worth_level: '',
},
adminIds: [
{
dept:[],
user:[],
adminData: []
}
],
applyIds: [
{
dept:[],
user:[],
applyData: []
}
],
deptData: [],
deptData1: [],
deptCodes: '',
deptCodes1: '',
rules: {
name: [
{
required: true,
message: '请输入产品名称及型号',
trigger: 'blur',
}
],
progress: [
{
required: true,
message: '请选择申请进度',
trigger: 'change',
}
],
patent_type_id: [
{
required: true,
message: '请选择专利类型',
trigger: 'change',
}
],
is_outcountry: [
{
required: true,
message: '请选择是否涉及国外',
trigger: 'change',
}
],
apply_country: [
{
required: true,
message: '请选择申请国家',
trigger: 'change',
}
],
worth_level: [
{
required: true,
message: '请选择价值级别',
trigger: 'change',
}
],
org_ids: [
{
required: true,
message: '请输入公司名称',
trigger: 'blur',
}
],
apply_time: [
{
type: 'date',
required: true,
message: '请选择申请时间',
trigger: 'change',
}
],
production_desc: [
{
required: true,
message: '请输入产品简介',
trigger: 'blur',
}
]
},
// adminData: [],
progress: [],
patentType: [],
worthLevel: [],
checkData: [],
applyData: [],
dialogVisible: false,
dialogImageUrl: '',
imgList: [],
fileList: [],
edit_params: {
admin_ids: [],
apply_man: [],
apply_country: "",
apply_result: "",
apply_time: "",
checkout_result: "",
is_outcountry: '',
name: "",
num: 0,
org_ids: "",
patent_type_id: '',
price: 0,
production_desc: "",
production_image: "",
progress: '',
publish_time: "",
renewals_time: "",
technical_disclosure: "",
total_price: 0,
worth_level: '',
},
curPath: ''
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + '/admin/patent/upload'
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags
})
},
created() {
this.getListData()
this.getAdminData()
this.curPath = this.$route.path
},
activated() {
},
beforeRouteLeave(to,from,next) {
const toPath = to.path
let flag = false
this.tags.forEach(cur => {
if (cur.path != this.curPath) {
flag = true
} else {
flag = false
}
})
if (flag == true) {
this.resetData()
}
next()
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
// 获取列表数据
getListData() {
this.$http.get('patent/constList').then(res => {
if (res.status == 200) {
const data = res.data.data
this.progress = data.progress
this.patentType = data.patent_type_id
this.worthLevel = data.worth_level
this.checkData = data.checkout_result
this.applyData = data.apply_result
}
})
},
// 获取项目负责人/申请人数据
getAdminData() {
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData = res.data.data
}
})
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData1 = res.data.data
}
})
},
// 设置禁用选项
setDisabled(data, data1) {
data.forEach(item => {
if (item.children) {
item.children.forEach(item1 => {
item1.disabled = false
if (item1.children) {
item1.children.forEach(item2 => {
item2.disabled = false
data1.forEach(ele => {
if (ele == item2.dept_code){
item2.disabled = true
}
})
})
} else {
data1.forEach(ele => {
if (ele == item1.dept_code){
item1.disabled = true
}
})
}
})
}
})
},
//选择项目负责人--部门数据
changeDept(val) {
this.deptCodes = val[val.length - 1]
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes }).then(res => {
if(res.status == 200) {
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.adminData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
selAdmin(val) {
console.log(val)
},
// 添加负责人
addAdmin() {
this.adminIds.push({ dept: [], user: [], adminData: []})
},
// 删除
deleteClick(item, index) {
console.log(item, index)
if (this.adminIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.adminIds.splice(index, 1)
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
// 申请人 -- 部门数据
changeDept1(val) {
this.deptCodes1 = val[val.length - 1]
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes1 }).then(res => {
if(res.status == 200) {
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.applyData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
selApply(val) {
console.log(val)
},
// 添加申请人
addApply() {
this.applyIds.push({ dept: [], user: [], applyData: []})
},
// 删除
deleteClick1(item, index) {
console.log(item, index)
if (this.applyIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.applyIds.splice(index, 1)
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
//文件上传成功时
handlePhotoSuccess(res, file, file_list) {
if (res.status == 200) {
this.edit_params.production_image = res.data.data.url
}
},
//logo
handlePhotoPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
//文件列表移除
handlePhotoRemove(file, fileList) {
this.edit_params.production_image = ''
},
//文件超出个数限制
handleExceed(files, fileList) {
const fileLen = files.length
const listLen = fileList.length
if (fileLen > 1 || listLen >= 1) {
this.$message({
message: '只能上传一张产品图片!',
type: 'warning'
})
return false
}
},
fileUpload(file) {
console.log(file)
const isLt5M = file.size / 1024 / 1024 < 10
if (!isLt5M) {
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
return false
}
// 文件格式拦截
const fileType = file.type
if (fileType != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' && fileType != 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' &&
fileType != 'application/pdf' && fileType != 'application/msword') {
this.$message({
message: '上传失败,当前文件格式无法上传!',
type: 'warning'
})
return false
}
},
// 进度
changeProgress(val) {
this.edit_params.progress = val
},
//技术交底书
handleSuccess(res, file, file_list) {
console.log(res)
if (res.status == 200) {
this.edit_params.technical_disclosure = res.data.data.url
}
},
handleRemove(file, fileList) {
this.edit_params.technical_disclosure = ''
},
// 修改负责人
changeAdmin(val) {
this.edit_params.admin_ids = val.join(',')
},
// 专利类型
changePatent(val) {
this.edit_params.patent_type_id = val
},
// 是否涉及国外
changeArea(val) {
console.log(val)
this.edit_params.is_outcountry = Number(val)
},
// 价值级别
changeWorth(val) {
this.edit_params.worth_level = val
},
// 查询结果
changeSearch(val) {
this.edit_params.checkout_result = val
},
// 申请结果
changeApply(val) {
this.edit_params.apply_result = val
},
// 申请时间
changeApplyTime(val) {
this.edit_params.apply_time = val
},
changePublishTime(val) {
this.edit_params.publish_time = val
},
changeRenewalsTime(val) {
this.edit_params.renewals_time = val
},
// 修改价格
changePrice(val) {
this.form.price = val
this.edit_params.price = val
// 数字,小数验证
const regu = '^[0-9]+([.]{1}[0-9]+){0,1}$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入数字/小数!'
})
this.form.price = ''
this.edit_params.price = ''
}
this.calculation(this.form.price, this.edit_params.num)
},
// 修改数量
changeNum(val) {
this.form.num = val
this.edit_params.num = val
// 正整数验证
const regu = '^[0-9]+$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入正整数!'
})
this.form.num = ''
this.edit_params.num = ''
}
this.calculation(this.edit_params.price, this.form.num)
},
// 计算合计费用
calculation(price, num) {
price = Number(price)
num = Number(num)
let total_price = 0
total_price = (price*num).toFixed(2)
console.log(total_price)
this.form.total_price = total_price
this.edit_params.total_price = total_price
},
//提交
submitClick(form) {
// 负责人
let admin_ids = []
let apply_man = []
this.adminIds.forEach(item => {
admin_ids.push({dept: item.dept, user: item.user})
})
this.edit_params.admin_ids = JSON.stringify(admin_ids)
// 申请人
this.applyIds.forEach(item => {
apply_man.push({dept: item.dept, user: item.user})
})
this.edit_params.apply_man = JSON.stringify(apply_man)
this.edit_params.name = this.form.name
this.edit_params.apply_country = this.form.apply_country
this.edit_params.org_ids = this.form.org_ids
this.edit_params.production_desc = this.form.production_desc
console.log(this.edit_params)
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message({
type: 'error',
message: '信息填写不完整!'
})
return false
} else {
this.$http.post('patent/save', this.edit_params ).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.resetData()
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/PIP/patent'
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
})
},
resetData() {
this.fileList = []
this.imgList = []
this.adminIds = [
{
dept:[],
user:[],
adminData: []
}
],
this.applyIds = [
{
dept:[],
user:[],
applyData: []
}
],
this.form = {
admin_ids: "",
apply_country: "",
apply_result: "",
apply_time: "",
checkout_result: "",
is_outcountry: '',
name: "",
num: 0,
org_ids: "",
patent_type_id: '',
price: "",
production_desc: "",
production_image: "",
progress: '',
publish_time: "",
renewals_time: "",
technical_disclosure: "",
total_price: "",
worth_level: '',
}
this.edit_params = {
admin_ids: "",
apply_country: "",
apply_result: "",
apply_time: "",
checkout_result: "",
is_outcountry: '',
name: "",
num: 0,
org_ids: "",
patent_type_id: '',
price: 0,
production_desc: "",
production_image: "",
progress: '',
publish_time: "",
renewals_time: "",
technical_disclosure: "",
total_price: 0,
worth_level: '',
}
}
}
}
</script>
<style scoped>
.basic_info{ border-bottom: 1px solid #dcdfe6;}
</style>

View File

@@ -0,0 +1,906 @@
<template>
<main>
<div class="bg_white m-20" style="margin-bottom: 70px;">
<div class="wrap text-black p-t-20 p-b-20 p-l-40 p-r-40">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" class="m-t-20" label-position="left">
<div class="basic_info">
<h3>基础信息</h3>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="编码" prop="" required>
<el-input v-model="form.id" style="width: 60%;" disabled="true" placeholder=""></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="专利名称" prop="name">
<el-input v-model="form.name" placeholder="请输入产品名称及型号" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请进度" prop="progress">
<el-select v-model="form.progress" placeholder="请选择申请进度" @change="changeProgress">
<el-option v-for="(item, index) in progress" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="项目负责人" prop="" required>
<template v-for="(item, index) in adminIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择项目负责人" filterable @change="selAdmin">
<el-option v-for="(item1, index1) in item.adminData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addAdmin"></i>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="申请人" prop="" required>
<template v-for="(item, index) in applyIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData1"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept1"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择申请人" filterable @change="selApply">
<el-option v-for="(item1, index1) in item.applyData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick1(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addApply"></i>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="专利类型" prop="patent_type_id">
<el-select v-model="form.patent_type_id" placeholder="请选择专利类型" @change="changePatent">
<el-option v-for="(item, index) in patentType" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="价值级别" prop="worth_level">
<el-select v-model="form.worth_level" placeholder="请选择价值级别" @change="changeWorth">
<el-option v-for="(item, index) in worthLevel" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请主体" prop="org_ids">
<el-input v-model="form.org_ids" placeholder="请输入公司名称" style="width: 60%;" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="是否涉及国外" prop="is_outcountry">
<el-select v-model="form.is_outcountry" placeholder="请选择是否涉及国外" @change="changeArea">
<el-option v-for="(item, index) in outcountry" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请国家" prop="apply_country">
<el-input v-model="form.apply_country" placeholder="多个国家间用“,”隔开" style="width: 60%;" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品简介" prop="production_desc">
<el-input maxlength="100" show-word-limit type="textarea" placeholder="请输入产品简介" v-model="form.production_desc" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="产品图片" prop="" required>
<el-upload
ref="upload"
:action="api_upload_url"
list-type="picture-card"
name="img"
:with-credentials = "true"
:on-success="handlePhotoSuccess"
:on-preview="handlePhotoPreview"
:limit="1"
:on-remove="handlePhotoRemove"
accept=".jpg,.png"
:on-exceed="handleExceed"
:file-list="imgList"
>
<el-button size="small" type="text"><i class="el-icon-plus"></i></el-button>
</el-upload>
<div class="el-upload__tip f_12 l_height_25">支持pngjpg格式, 上限1M</div>
<el-dialog v-model="dialogVisible">
<el-image width="100%" :src="dialogImageUrl" alt=""></el-image>
</el-dialog>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="技术交底书" prop="" required>
<el-upload
class="upload-demo"
:action="api_upload_url"
:with-credentials = "true"
:on-success="handleSuccess"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="fileUpload"
:limit="1"
accept=".pdf, .xlsx, .docx, .doc, .xls"
:file-list="fileList"
>
<el-button size="small" type="primary">上传</el-button>
<template #tip>
<div class="el-upload__tip">
支持PDFWordExcel格式限10M内
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="others">
<el-row>
<el-col :span="12">
<h3>查询结果</h3>
<el-radio-group v-model="form.checkout_result" @change="changeSearch">
<el-radio v-for="(item, index) in checkData" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<h3>申请结果</h3>
<el-radio-group v-model="form.apply_result" @change="changeApply">
<el-radio v-for="(item, index) in applyData" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<h3>时间进度</h3>
<el-row>
<el-col :span="8">
<el-form-item label="申请时间" prop="apply_time">
<el-date-picker
v-model="form.apply_time"
type="date"
placeholder="请选择申请时间"
value-format="YYYY-MM-DD"
@change="changeApplyTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="公告时间">
<el-date-picker
v-model="form.publish_time"
type="date"
placeholder="请选择公告时间"
value-format="YYYY-MM-DD"
@change="changePublishTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="续费时间">
<el-date-picker
v-model="form.renewals_time"
type="date"
placeholder="请选择续费时间"
value-format="YYYY-MM-DD"
@change="changeRenewalsTime">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<h3>费用信息</h3>
<el-row>
<el-col :span="8">
<el-form-item label="单价" prop="">
<el-input v-model="form.price" style="width: 60%;" placeholder="仅限数字,支持小数" @change="changePrice"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="">
<el-input v-model="form.num" style="width: 60%;" placeholder="仅限正整数" @change="changeNum"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总计" prop="">
<el-input v-model="form.total_price" style="width: 60%;" placeholder="" disabled="true"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</div>
<div class="bg_white m-t-10 p-l-20 p-r-20 p-t-10 p-b-10 text-black footer" style="width:100%;">
<el-button type="primary" class="search_button" @click="submitClick('form')">提交</el-button>
</div>
</main>
</template>
<script>
import { reactive } from 'vue';
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
id: '',
form: {
admin_ids: [],
apply_man: [],
apply_country: "",
apply_result: "",
apply_time: "",
checkout_result: "",
is_outcountry: '',
name: "",
num: 0,
org_ids: "",
patent_type_id: '',
price: 0,
production_desc: "",
production_image: "",
progress: '',
publish_time: "",
renewals_time: "",
technical_disclosure: "",
total_price: 0,
worth_level: '',
},
adminIds: [],
applyIds: [],
deptData: [],
deptData1: [],
deptCodes: '',
deptCodes1: '',
rules: {
name: [
{
required: true,
message: '请输入产品名称及型号',
trigger: 'blur',
}
],
progress: [
{
required: true,
message: '请选择申请进度',
trigger: 'change',
}
],
patent_type_id: [
{
required: true,
message: '请选择专利类型',
trigger: 'change',
}
],
is_outcountry: [
{
required: true,
message: '请选择是否涉及国外',
trigger: 'change',
}
],
apply_country: [
{
required: true,
message: '请选择申请国家',
trigger: 'change',
}
],
worth_level: [
{
required: true,
message: '请选择价值级别',
trigger: 'change',
}
],
org_ids: [
{
required: true,
message: '请输入公司名称',
trigger: 'blur',
}
],
apply_time: [
{
type: 'date',
required: true,
message: '请选择申请时间',
trigger: 'change',
}
],
production_desc: [
{
required: true,
message: '请输入产品简介',
trigger: 'blur',
}
]
},
// adminData: [],
progress: [],
patentType: [],
worthLevel: [],
checkData: [],
applyData: [],
dialogVisible: false,
dialogImageUrl: '',
imgList: [],
fileList: [],
outcountry: [
{
id: 0,
name: '否'
},
{
id: 1,
name: '是'
}
],
edit_params: {
admin_ids: "",
apply_man: '',
apply_country: "",
apply_result: "",
apply_time: "",
checkout_result: "",
id: '',
is_outcountry: 1,
name: "",
num: 0,
org_ids: "",
patent_type_id: '',
price: "",
production_desc: "",
production_image: "",
progress: 1,
publish_time: "",
renewals_time: "",
technical_disclosure: "",
total_price: "",
worth_level: 1,
}
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + '/admin/patent/upload'
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags
})
},
created() {
this.getListData()
this.getAdminData()
},
activated() {
this.id = this.$route.query.id
this.getDetail()
},
beforeRouteUpdate(to,from,next){
this.id = to.query.id
if(to.fullPath!=from.fullPath){
this.getDetail()
next()
}
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
// 获取列表数据
getListData() {
this.$http.get('patent/constList').then(res => {
if (res.status == 200) {
const data = res.data.data
this.progress = data.progress
this.patentType = data.patent_type_id
this.worthLevel = data.worth_level
this.checkData = data.checkout_result
this.applyData = data.apply_result
}
})
},
// 获取项目负责人数据
getAdminData() {
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData = res.data.data
}
})
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData1 = res.data.data
}
})
},
// 设置禁用选项
setDisabled(data, data1) {
data.forEach(item => {
if (item.children) {
item.children.forEach(item1 => {
item1.disabled = false
if (item1.children) {
item1.children.forEach(item2 => {
item2.disabled = false
data1.forEach(ele => {
if (ele == item2.dept_code){
item2.disabled = true
}
})
})
} else {
data1.forEach(ele => {
if (ele == item1.dept_code){
item1.disabled = true
}
})
}
})
}
})
},
//选择项目负责人--部门数据
changeDept(val) {
this.deptCodes = val[val.length - 1]
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes }).then(res => {
if(res.status == 200) {
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.adminData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
selAdmin(val) {
console.log(val)
},
// 添加负责人
addAdmin() {
this.adminIds.push({ dept: [], user: [], adminData: []})
},
// 删除
deleteClick(item, index) {
console.log(item, index)
if (this.adminIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.adminIds.splice(index, 1)
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
// 申请人 -- 部门数据
changeDept1(val) {
console.log(val)
this.deptCodes1 = val[val.length - 1]
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes1 }).then(res => {
if(res.status == 200) {
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.applyData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
selApply(val) {
console.log(val)
},
// 添加申请人
addApply() {
this.applyIds.push({ dept: [], user: [], applyData: []})
},
// 删除
deleteClick1(item, index) {
console.log(item, index)
if (this.applyIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.applyIds.splice(index, 1)
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
// 数据回显
getDepartment(val, type) {
let deptCodes = ''
deptCodes = val[val.length - 1]
this.$http.get('brand/getUserListByDeptCode', { dept_code: deptCodes }).then(res => {
if(res.status == 200) {
if (type == 1) {
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (deptCodes == item1) {
item.adminData = res.data.data
}
})
})
this.adminIds = reactive(this.adminIds)
} else {
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (deptCodes == item1) {
item.applyData = res.data.data
}
})
})
this.applyIds = reactive(this.applyIds)
}
// 获取需要禁用的项
let arr = []
if (type == 1) {
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
this.setDisabled(this.deptData, arr)
} else {
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
this.setDisabled(this.deptData1, arr)
}
}
})
},
// 专利详情
getDetail() {
this.$http.get('patent/read/id', { id: this.id }).then(res => {
console.log(res)
if (res.status == 200) {
this.form = res.data.data
this.imgList = [{name: 'logo', url: this.form.production_image}]
this.fileList = [{name: '技术交底书', url: this.form.technical_disclosure}]
this.dialogImageUrl = this.form.production_image
this.form.apply_result = Number(this.form.apply_result)
this.form.checkout_result = Number(this.form.checkout_result)
// 处理负责人的数据回显
const data = this.form.admin_ids
data.forEach(item => {
this.getDepartment(item.dept, 1)
})
this.adminIds = data
//申请人的数据回显
const data1 = this.form.apply_man
data1.forEach(item => {
this.getDepartment(item.dept, 2)
})
this.applyIds = data1
// 未做修改直接保存
let admin_ids = []
let apply_man = []
this.adminIds.forEach(item => {
admin_ids.push({dept: item.dept, user: item.user})
})
this.edit_params.admin_ids = JSON.stringify(admin_ids)
// 申请人
this.applyIds.forEach(item => {
apply_man.push({dept: item.dept, user: item.user})
})
this.edit_params.apply_man = JSON.stringify(apply_man)
this.edit_params = {
admin_ids: this.form.admin_ids,
apply_country: this.form.apply_country,
apply_result: this.form.apply_result,
apply_time: this.form.apply_time,
checkout_result: this.form.checkout_result,
id: this.form.id,
is_outcountry: this.form.is_outcountry,
name: this.form.name,
num: this.form.num,
org_ids: this.form.org_ids,
patent_type_id: this.form.patent_type_id,
price: this.form.price,
production_desc: this.form.production_desc,
production_image: this.imgList[0].url,
progress: this.form.progress,
publish_time: this.form.publish_time,
renewals_time: this.form.renewals_time,
technical_disclosure: this.fileList[0].url,
total_price: this.form.total_price,
worth_level: this.form.worth_level,
}
if (this.edit_params.admin_ids) {
this.edit_params.admin_ids = this.edit_params.admin_ids.join(',')
}
}
})
},
//文件上传成功时
handlePhotoSuccess(res, file, file_list) {
if (res.status == 200) {
this.edit_params.production_image = res.data.data.url
}
},
//logo
handlePhotoPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
//文件列表移除
handlePhotoRemove(file, fileList) {
this.edit_params.production_image = ''
},
//文件超出个数限制
handleExceed(files, fileList) {
const fileLen = files.length
const listLen = fileList.length
if (fileLen > 1 || listLen >= 1) {
this.$message({
message: '只能上传一张产品图片!',
type: 'warning'
})
return false
}
},
fileUpload(file) {
console.log(file)
const isLt5M = file.size / 1024 / 1024 < 10
if (!isLt5M) {
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
return false
}
// 文件格式拦截
const fileType = file.type
if (fileType != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' && fileType != 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' &&
fileType != 'application/pdf' && fileType != 'application/msword') {
this.$message({
message: '上传失败,当前文件格式无法上传!',
type: 'warning'
})
return false
}
},
// 进度
changeProgress(val) {
this.edit_params.progress = val
},
//技术交底书
handleSuccess(res, file, file_list) {
if (res.status == 200) {
this.edit_params.technical_disclosure = res.data.data.url
}
},
handleRemove(file, fileList) {
this.edit_params.technical_disclosure = ''
},
// 修改负责人
// changeAdmin(val) {
// this.edit_params.admin_ids = val.join(',')
// },
// 专利类型
changePatent(val) {
this.edit_params.patent_type_id = val
},
// 是否涉及国外
changeArea(val) {
this.edit_params.is_outcountry = Number(val)
},
// 价值级别
changeWorth(val) {
this.edit_params.worth_level = val
},
// 查询结果
changeSearch(val) {
this.edit_params.checkout_result = val
},
// 申请结果
changeApply(val) {
this.edit_params.apply_result = val
},
// 申请时间
changeApplyTime(val) {
this.edit_params.apply_time = val
},
changePublishTime(val) {
this.edit_params.publish_time = val
},
changeRenewalsTime(val) {
this.edit_params.renewals_time = val
},
// 修改价格
changePrice(val) {
this.form.price = val
this.edit_params.price = val
// 数字,小数验证
const regu = '^[0-9]+([.]{1}[0-9]+){0,1}$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入数字/小数!'
})
this.form.price = ''
this.edit_params.price = ''
}
this.calculation(this.form.price, this.edit_params.num)
},
// 修改数量
changeNum(val) {
this.form.num = val
this.edit_params.num = val
// 正整数验证
const regu = '^[0-9]+$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入正整数!'
})
this.form.num = ''
this.edit_params.num = ''
}
this.calculation(this.edit_params.price, this.form.num)
},
// 计算合计费用
calculation(price, num) {
price = Number(price)
num = Number(num)
let total_price = 0
total_price = (price*num).toFixed(2)
console.log(total_price)
this.form.total_price = total_price
this.edit_params.total_price = total_price
},
//提交
submitClick(form) {
// 负责人
let admin_ids = []
let apply_man = []
this.adminIds.forEach(item => {
admin_ids.push({dept: item.dept, user: item.user})
})
this.edit_params.admin_ids = JSON.stringify(admin_ids)
// 申请人
this.applyIds.forEach(item => {
apply_man.push({dept: item.dept, user: item.user})
})
this.edit_params.apply_man = JSON.stringify(apply_man)
this.edit_params.name = this.form.name
this.edit_params.apply_country = this.form.apply_country
this.edit_params.org_ids = this.form.org_ids
this.edit_params.production_desc = this.form.production_desc
console.log(this.edit_params)
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message({
type: 'error',
message: '信息填写不完整!'
})
return false
} else {
this.$http.put('patent/update/id', this.edit_params ).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.getDetail()
this.fileList = []
this.imgList = []
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/PIP/patent'
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
})
}
}
}
</script>
<style scoped>
.basic_info{ border-bottom: 1px solid #dcdfe6;}
</style>

View File

@@ -0,0 +1,379 @@
<template>
<main class="m-20">
<div class="wrap text-black">
<!--顶部搜索-->
<el-row class="bg_white searchBox">
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="100px" class="m-t-20">
<el-row>
<el-col :span="6">
<el-form-item label="供应商" prop>
<el-input v-model="filter.supplier" placeholder="请输入单个供应商名称查询"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="采购订单号" prop>
<el-input v-model="filter.pur_order_sn" placeholder="仅支持单个采购订单号"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="销售订单号" prop>
<el-input v-model="filter.sale_order_sn" placeholder="仅支持单个销售订单号"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="送货单号" prop>
<el-input v-model="filter.delivery_order_sn" placeholder="仅支持单个送货单号"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="sku/产品型号" prop>
<el-input v-model="filter.sku" placeholder="搜索多个sku时用逗号隔开"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="检测状态" prop>
<el-select v-model="filter.status" placeholder="请选择检测状态">
<el-option label="全部" value="-1"></el-option>
<el-option label="已检测" value="0"></el-option>
<el-option label="未检测" value="1"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4" :offset="2">
<el-button type="primary" @click="searchClick">搜索</el-button>
<el-button type="primary" @click="reset">重置</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<!--table-->
<el-row class="bg_white m-t-20">
<el-col :span="24">
<el-row class="m-t-20">
<el-col :span="6" class="m-l-40">
<el-button type="primary" @click="makeSure(1)">确认</el-button>
<el-button type="primary" @click="makeSure(0)">反确认</el-button>
</el-col>
</el-row>
<el-table
class="m-20"
:data="tableData"
style="width: auto;"
border
ref="multipleTable"
:header-cell-style="header_style"
@selection-change="handleSelectionChange"
:row-key="getRowKeys"
>
<el-table-column type="selection" :reserve-selection="true" width="55" align="center"></el-table-column>
<el-table-column fixed prop="sale_order_sn" label="销售订单号" width="180" align="center" />
<el-table-column fixed prop="pur_order_sn" label="采购订单号" width="180" />
<el-table-column prop="delivery_order_sn" label="送货单号" width="180" fixed />
<el-table-column prop="source" label="来源系统" />
<el-table-column prop="supplier" label="供应商/生产厂名" width="180" />
<el-table-column prop="sku" label="sku/产品型号" width="180" lign="center" />
<el-table-column prop="name" label="物料名称" align="center" />
<el-table-column prop="check_status" label="检测状态" align="center" />
<el-table-column prop label="检测报告" width="180" align="center">
<template #default="scope">
<el-upload
v-if="!scope.row.report_url"
:action="api_upload_url"
:with-credentials="true"
:on-success="function (res, file, file_list) {return handleSuccess(res, file, file_list, scope.row)}"
:show-file-list="false"
name="file"
ref="upload"
v-loading.fullscreen.lock="loading"
:on-change="handleChange"
>
<span class="text_blue Cursor m-r-10">上传</span>
</el-upload>
<div v-else>
<span @click="downloadTemplate(scope.row)" class="text_blue Cursor m-r-10">下载</span>
<span @click="deleteFile(scope.row, scope.$index)" class="text_blue Cursor">删除</span>
</div>
</template>
</el-table-column>
<el-table-column prop="confirm_status" label="确认状态" align="center" />
<el-table-column prop="num" label="送检数量(pcs)" width="180" align="center" />
<el-table-column prop="depot" label="送货仓库" align="center" />
<el-table-column prop="supplier_addr" label="供应商地址" width="180" align="center" />
<el-table-column prop="contact_mobile" label="联络人/电话号码" width="180" align="center" />
<el-table-column prop="scheck_date" label="送检日期" align="center" />
<el-table-column prop="check_date" label="检测日期" align="center" />
<el-table-column prop="check_user" label="检测人" align="center" />
<el-table-column prop="confirm_name" label="确认人" align="center" />
<el-table-column prop="remark" label="备注" width="180" align="center" />
</el-table>
<el-row class="p-20">
<el-pagination
@size-change="changePageSize"
@current-change="changePage"
:current-page="filter.page"
:page-sizes="[50, 100, 150, 200]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</main>
</template>
<script>
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: 'copyRight',
data() {
return {
loading: false,
api_upload_url: '',
fileList: [], //上传的文件列表
header_style: {
'background-color': '#F5F7FA',
color: '#606266',
fontSize: '14px',
fontWeight: '600',
textAlign: 'center'
},
form: {},
tableData: [],
currentPage: 1,
total: 0,
filter: {
page: 1,
size: 50,
supplier: '',
pur_order_sn: '',
sale_order_sn: '',
delivery_order_sn: '',
sku: '',
status: '-1'
},
getRowKeys(row) {
//记录每行的key值
return row.id
},
select_number: '', //表格select选中的条数
select_Id: [], //表格select复选框选中的id
multipleSelection: [],
multiplearry: []
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + 'admin/Upload/file'
}
},
mounted() {
this.multiplearry = []
},
activated() {
this.getList()
},
methods: {
deleteFile(item) {
this.$confirm('确认删除该质检报告?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http.get('/qorder/delete_report', { id: item.id }).then(res => {
if (res.errno == 200)
this.$message({
type: 'success',
message: '删除成功!'
})
this.getList()
})
})
},
//上传
handleSuccess(res, file, file_list, item) {
if (res.status == 200) {
this.$http.post('qorder/upload_report', { id: item.id, report_url: res.data.imgpath }).then(ress => {
if (ress.errno == 200) {
this.getList()
this.$message({
type: 'success',
message: ress.errmsg
})
} else {
this.$message({
type: 'error',
message: ress.errmsg
})
}
this.loading = false
})
} else {
file_list.splice(file_list.length - 1, 1)
this.$message({
type: 'error',
message: res.errmsg
})
}
},
//上传文件限制
handleChange(file, fileList) {
this.loading = true
const isLt5M = file.size / 1024 / 1024 < 10
if (!isLt5M) {
this.$message({
type: 'error',
message: '上传文件大小不能超过 10MB'
})
file = null
fileList = []
this.$refs.upload.clearFiles() // 清除前端显示的文件列表
this.loading = false
}
},
// 勾选
handleSelectionChange(rows) {
this.multipleSelection = rows
this.select_number = this.multipleSelection.length
this.select_Id = []
if (rows) {
rows.forEach(row => {
if (row) {
this.select_Id.push(row.id)
}
})
}
console.log(rows, this.select_number, this.select_Id)
},
// 确认
makeSure(status) {
if (this.select_Id && this.select_Id.length > 0) {
//status--0反确认 1确认
this.$http.get('qorder/list', { ids: this.select_Id.join(','), status: status }).then(res => {
if (res.errno == 200) {
this.$message.success('确认成功')
this.$refs.multipleTable.clearSelection()
}
})
} else {
this.$message.warning('请先确认勾选,在操作!')
}
},
//搜索
searchClick() {
this.filter.page = 1
this.filter.size = 10
this.getList()
},
// 重置
reset() {
this.filter = {
page: 1,
size: 10,
supplier: '',
pur_order_sn: '',
sale_order_sn: '',
delivery_order_sn: '',
sku: '',
status: ''
}
this.isCopyright = true
this.getList()
},
//版权list
getList() {
this.$http.get('qorder/list', this.filter).then(res => {
if (res.errno == 200) {
this.tableData = res.data.data
this.total = res.data.total
this.$refs.multipleTable.toggleRowSelection(this.multiplearry)
}
})
},
// 改变每页请求条数
changePageSize(size) {
this.filter.size = size
this.getList()
},
// 翻页
changePage(page) {
this.filter.page = page
this.getList()
},
// 删除
deleteClick(row, index) {
ElMessageBox.confirm('确认删除该专利?', '提示', {
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.delete('copyright/delete/id?id=' + row.id).then(res => {
if (res.status == 200) {
this.getList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
// 下载
downloadTemplate(data) {
this.$message({
type: 'success',
message: '正在下载,请稍后...'
})
let url = ''
if (data == '') {
url = this.url
} else {
url = data.report_url
}
axios
.get(url, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
})
.then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const url_arr = res.config.url.split('/')
const nameStr = decodeURI(url_arr[url_arr.length - 1])
console.log(nameStr)
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
}
}
}
</script>
<style scoped>
.wrap {
width: auto;
}
</style>

408
src/views/PIP/trademark.vue Normal file
View File

@@ -0,0 +1,408 @@
<template>
<main class="m-20">
<div class="wrap text-black">
<!--顶部搜索-->
<el-row class="bg_white searchBox">
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="100px" class="m-t-20">
<el-row>
<el-col :span="6">
<el-form-item label="名称" prop="">
<el-input v-model="filter.name" style="width: 220px;" placeholder="请输入商标名称/申请国家/公司名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请类目" prop="">
<el-select v-model="filter.product_category" placeholder="请选择申请类目">
<el-option v-for="(item, index) in category" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="公告时间" prop="">
<el-date-picker
v-model="filter.publish_time"
type="date"
placeholder="请选择公告时间"
value-format="YYYY-MM-DD"
@change="changePublishTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="续费时间" prop="">
<el-date-picker
v-model="filter.renewals_time"
type="date"
placeholder="请选择续费时间"
value-format="YYYY-MM-DD"
@change="changeRenewalsTime">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="项目负责人" prop="">
<el-cascader
v-model="depts"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept"
>
</el-cascader>
<el-select v-model="admin_ids" placeholder="请选择项目负责人" @change="selLeader">
<el-option v-for="(item, index) in adminData" :key="index" :label="item.staff_name" :value="item.staff_code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" :offset="1">
<el-form-item label="申请人" prop="">
<el-cascader
v-model="admins"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept1"
>
</el-cascader>
<el-select v-model="apply_man" placeholder="请选择申请人" @change="changeAdmin">
<el-option v-for="(item, index) in adminData1" :key="index" :label="item.staff_name" :value="item.staff_code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4" :offset="3">
<el-button type="primary" @click="searchClick">搜索</el-button>
<el-button type="primary" @click="reset">重置</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<!--table-->
<el-row class="bg_white m-t-20">
<el-col :span="24">
<el-row class="m-t-20">
<el-col :span="6" class="m-l-40">
<el-button type="primary" @click="addClick">新增商标</el-button>
<el-button class="m-l-10" type="primary" @click="downloadCategory">下载产品类目表</el-button>
</el-col>
</el-row>
<el-table class="m-20" :data="tableData" style="width: auto;" border :header-cell-style="header_style">
<el-table-column fixed prop="id" label="编码" width="80" align="center" />
<el-table-column fixed prop="name" label="商标名称" width="180">
<template #default="scope">
<span @click="editClick(scope.row)" class="text_blue Cursor">{{scope.row.name}}</span>
</template>
</el-table-column>
<el-table-column prop="admin_ids" label="项目负责人" width="180" />
<el-table-column prop="progress" label="申请进度" width="180" />
<el-table-column prop="org_ids" label="申请主体" width="180" />
<el-table-column prop="apply_man" label="申请人" width="120" />
<el-table-column prop="register_country" label="注册国家" width="100" align="center" />
<el-table-column prop="" label="logo" align="center">
<template #default="scope">
<el-image :src="scope.row.logo" style="width:50px; height:50px"></el-image>
</template>
</el-table-column>
<el-table-column prop="product_category" label="使用产品类目" width="180" />
<el-table-column prop="search_result" label="查询结果" width="120" />
<el-table-column prop="apply_result" label="申请结果" width="180" />
<el-table-column prop="apply_time" label="申请时间" width="180" />
<el-table-column prop="publish_time" label="公告时间" width="180" />
<el-table-column prop="renewals_time" label="续费时间" width="180" />
<el-table-column prop="price" label="单价(¥)" width="100" align="center" />
<el-table-column prop="num" label="数量" align="center" />
<el-table-column prop="total_price" label="总计(¥)" width="100" align="center" />
<el-table-column prop="" label="操作" width="180" align="center">
<template #default="scope">
<span @click="editClick(scope.row)" class="text_blue Cursor m-r-10">查看详情</span>
<span @click="deleteClick(scope.row, scope.$index)" class="text_blue Cursor">删除</span>
</template>
</el-table-column>
</el-table>
<el-row class=" p-20">
<el-pagination
class="pagination"
v-model="currentPage"
:page-size="filter.size"
layout="total, prev, pager, next"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</main>
</template>
<script>
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: 'trademark',
data() {
return {
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
form: {
name: '',
leader: [],
progress: [],
applyTime: '',
bulletinTime: '',
renewalTime: ''
},
tableData: [],
currentPage: 1,
total: 0,
filter: {
page: 1,
size: 10,
name: '',
admin_ids: '',
product_category: '',
apply_man: '',
publish_time: '',
renewals_time: ''
},
adminData: [],
progress: [],
category: [],
url: '',
name: '',
depts: [],
admins: [],
admin_ids: '',
apply_man: '',
deptData: [],
deptCodes: '',
deptCodes1: '',
adminData1: []
}
},
created() {
this.getListData()
this.getAdminData()
this.getUrl()
},
activated() {
this.getList()
},
methods: {
// 获取下载链接
getUrl() {
this.$http.get('brand/productCategoryTemplate').then(res => {
if(res.status == 200) {
this.url = res.data.data.url
this.name = res.data.data.name
}
})
},
//选择负责人
changeDept(val) {
this.deptCodes = val
const dept_code = val[val.length - 1]
this.$http.get('brand/getUserListByDeptCode', { dept_code: dept_code }).then(res => {
if (res.status == 200) {
this.adminData = res.data.data
}
})
},
selLeader(val) {
let admin_ids = {dept: [], user: []}
admin_ids.dept = this.deptCodes
admin_ids.user.push(val)
this.filter.admin_ids = JSON.stringify(admin_ids)
},
//申请人
changeDept1(val) {
this.deptCodes1 = val
const dept_code = val[val.length - 1]
this.$http.get('brand/getUserListByDeptCode', { dept_code: dept_code }).then(res => {
if (res.status == 200) {
this.adminData1 = res.data.data
}
})
},
changeAdmin(val) {
console.log(val)
let apply_ids = {dept: [], user: []}
apply_ids.dept = this.deptCodes1
apply_ids.user.push(val)
this.filter.apply_man = JSON.stringify(apply_ids)
},
//选择进度
selProgress(val) {
this.filter.progress = val
},
// 申请时间
changeApplyTime(val) {
console.log(val)
this.filter.apply_time = val
},
changePublishTime(val) {
this.filter.publish_time = val
},
changeRenewalsTime(val) {
this.filter.renewals_time = val
},
//搜索
searchClick() {
this.filter.page = 1
this.filter.size = 10
this.getList()
},
// 重置
reset() {
this.filter = {
page: 1,
size: 10,
name: '',
admin_ids: '',
apply_man: '',
progress: '',
apply_time: '',
publish_time: '',
renewals_time: ''
}
this.depts = []
this.admins = []
this.admin_ids = ''
this.apply_man = ''
this.getList()
},
// 获取列表数据
getListData() {
this.$http.get('brand/constList').then(res => {
if (res.status == 200) {
const data = res.data.data
this.progress = data.progress
this.category = data.product_category
}
})
},
// 获取项目负责人数据
getAdminData() {
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData = res.data.data
}
})
},
//商标list
getList() {
this.$http.get('brand/index', this.filter).then(res => {
console.log(res)
if (res.status == 200 ) {
this.tableData = res.data.data.data
this.total = res.data.data.count
}
})
},
// 改变每页请求条数
changePageSize(size) {
this.filter.size = size;
this.getList();
},
// 翻页
changePage(page) {
this.filter.page = page;
this.getList();
},
// 新增商标
addClick() {
this.$router.push({
path: '/PIP/trademark_add'
})
},
// 编辑
editClick(row) {
this.$router.push({
path: '/PIP/trademark_edit',
query: {
id: row.id
}
})
},
// 删除
deleteClick(row, index) {
ElMessageBox.confirm('确认删除该商标?', '提示', {
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.delete('brand/delete/id?id=' + row.id ).then(res => {
if (res.status == 200) {
this.getList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
// 下载类目表
downloadCategory() {
this.$message({
type: 'success',
message: '正在下载,请稍后...'
})
axios.get( this.url, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
}).then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const url_arr = res.config.url.split('/')
const nameStr = decodeURI(url_arr[url_arr.length - 1])
console.log(nameStr)
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
}
}
}
</script>
<style scoped>
.wrap{ width: auto;}
</style>

View File

@@ -0,0 +1,747 @@
<template>
<main>
<div class="bg_white m-20" style="margin-bottom: 70px;">
<div class="wrap text-black p-t-20 p-b-20 p-l-40 p-r-40">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" class="m-t-20" label-position="left">
<div class="basic_info">
<h3>基础信息</h3>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="编码" prop="" required>
<el-input v-model="form.id" style="width: 60%;" disabled="true" placeholder="编码自动生成"></el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="商标名称" prop="name">
<el-input v-model="form.name" style="width: 60%;" placeholder="请输入商标名称"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="项目负责人" prop="" required>
<template v-for="(item, index) in adminIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择项目负责人" filterable @change="selAdmin">
<el-option v-for="(item1, index1) in item.adminData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addAdmin"></i>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="申请人" prop="" required>
<template v-for="(item, index) in applyIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData1"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept1"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择申请人" filterable @change="selApply">
<el-option v-for="(item1, index1) in item.applyData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick1(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addApply"></i>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="注册国家" prop="register_country">
<el-input v-model="form.register_country" placeholder="多个国家间用“,”隔开" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="申请主体" prop="org_ids">
<el-input v-model="form.org_ids" placeholder="请输入公司名称" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="申请进度" prop="progress">
<el-select v-model="form.progress" placeholder="请选择申请进度" @change="changeProgress">
<el-option v-for="(item, index) in progress" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="产品使用类目" prop="product_category">
<el-select v-model="form.product_category" multiple placeholder="请选择产品使用类目" @change="changeCategory">
<el-option v-for="(item, index) in category" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="LOGO" prop="" required>
<el-upload
ref="upload"
:action="api_upload_url"
list-type="picture-card"
name="img"
:with-credentials = "true"
:on-success="handlePhotoSuccess"
:on-preview="handlePhotoPreview"
:limit="1"
:on-remove="handlePhotoRemove"
accept=".jpg,.png"
:on-exceed="handleExceed"
:file-list="fileList"
>
<el-button size="small" type="text"><i class="el-icon-plus"></i></el-button>
</el-upload>
<div class="el-upload__tip f_12 l_height_25">支持pngjpg格式, 上限1M</div>
<el-dialog v-model="dialogVisible">
<el-image width="100%" :src="dialogImageUrl" alt=""></el-image>
</el-dialog>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="others">
<el-row>
<el-col :span="12">
<h3>查询结果</h3>
<el-radio-group v-model="form.search_result" @change="changeSearch">
<el-radio v-for="(item, index) in query" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<h3>申请结果</h3>
<el-radio-group v-model="form.apply_result" @change="changeApply">
<el-radio v-for="(item, index) in result" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<h3>时间进度</h3>
<el-row>
<el-col :span="8">
<el-form-item label="申请时间" prop="apply_time">
<el-date-picker
v-model="form.apply_time"
type="date"
placeholder="请选择申请时间"
value-format="YYYY-MM-DD"
@change="changeApplyTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="公告时间">
<el-date-picker
v-model="form.publish_time"
type="date"
placeholder="请选择公告时间"
value-format="YYYY-MM-DD"
@change="changePublishTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="续费时间">
<el-date-picker
v-model="form.renewals_time"
type="date"
placeholder="请选择续费时间"
value-format="YYYY-MM-DD"
@change="changeRenewalsTime">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<h3>费用信息</h3>
<el-row>
<el-col :span="8">
<el-form-item label="单价" prop="">
<el-input v-model="form.price" style="width: 60%;" placeholder="仅限数字,支持小数" @change="changePrice"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="">
<el-input v-model="form.num" style="width: 60%;" placeholder="仅限正整数" @change="changeNum"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总计" prop="">
<el-input v-model="form.total_price" style="width: 60%;" placeholder="自动计算" disabled="true"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</div>
<div class="bg_white m-t-10 p-l-20 p-r-20 p-t-10 p-b-10 text-black footer" style="width:100%;">
<el-button type="primary" class="search_button" @click="submitClick('form')">提交</el-button>
</div>
</main>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
id: '',
form: {
admin_ids: [],
apply_man: [],
apply_result: '',
apply_time: "",
id: '',
logo: "",
name: "",
num: '',
org_ids: "",
price: '',
product_category: [],
progress: '',
publish_time: "",
register_country: '',
renewals_time: "",
search_result: '',
total_price: ''
},
adminIds: [
{
dept:[],
user:[],
adminData: []
}
],
applyIds: [
{
dept:[],
user:[],
applyData: []
}
],
rules: {
name: [
{
required: true,
message: '请输入商标名称',
trigger: 'blur',
}
],
progress: [
{
required: true,
message: '请选择申请进度',
trigger: 'change',
}
],
register_country: [
{
required: true,
message: '请输入注册国家',
trigger: 'blur',
}
],
org_ids: [
{
required: true,
message: '请输入公司名称',
trigger: 'blur',
}
],
product_category: [
{
required: true,
message: '请选择产品使用类目',
trigger: 'change',
}
],
apply_time: [
{
type: 'date',
required: true,
message: '请选择申请时间',
trigger: 'change',
}
]
},
dialogVisible: false,
dialogImageUrl: '',
// adminData: [],
progress: [],
category: [],
query: [],
result: [],
fileList: [],
add_params: {
admin_ids: [],
apply_man: [],
apply_result: '',
apply_time: "",
id: '',
logo: "",
name: "",
num: 0,
org_ids: "",
price: 0,
product_category: "",
progress: '',
publish_time: "",
register_country: "",
renewals_time: "",
search_result: '',
total_price: 0
},
deptData: [],
deptData1: [],
deptCodes: '',
deptCodes1: '',
curPath: ''
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + '/admin/brand/upload'
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags
})
},
created() {
this.getListData()
this.getAdminData()
this.curPath = this.$route.path
},
activated() {
// this.resetData()
},
beforeRouteLeave(to,from,next) {
const toPath = to.path
let flag = false
this.tags.forEach(cur => {
if (cur.path != this.curPath) {
flag = true
} else {
flag = false
}
})
if (flag == true) {
this.resetData()
}
next()
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
// 获取列表数据
getListData() {
this.$http.get('brand/constList').then(res => {
if (res.status == 200) {
const data = res.data.data
this.progress = data.progress
this.category = data.product_category
this.query = data.search_result
this.result = data.apply_result
}
})
},
// 获取项目负责人/申请人数据
getAdminData() {
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData = res.data.data
}
})
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData1 = res.data.data
}
})
},
// 设置禁用选项
setDisabled(data, data1) {
data.forEach(item => {
if (item.children) {
item.children.forEach(item1 => {
item1.disabled = false
if (item1.children) {
item1.children.forEach(item2 => {
item2.disabled = false
data1.forEach(ele => {
if (ele == item2.dept_code){
item2.disabled = true
}
})
})
} else {
data1.forEach(ele => {
if (ele == item1.dept_code){
item1.disabled = true
}
})
}
})
}
})
},
//选择项目负责人--部门数据
changeDept(val) {
this.deptCodes = val[val.length - 1]
this.adminIds.forEach((item, index) => {
// item.isDisabled = true
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.user = []
// item.isDisabled = false
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes }).then(res => {
if(res.status == 200) {
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.adminData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
selAdmin(val) {
console.log(val)
},
// 添加负责人
addAdmin() {
this.adminIds.push({ dept: [], user: [], adminData: []})
},
// 删除
deleteClick(item, index) {
console.log(item, index)
if (this.adminIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.adminIds.splice(index, 1)
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
// 申请人 -- 部门数据
changeDept1(val) {
this.deptCodes1 = val[val.length - 1]
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes1 }).then(res => {
if(res.status == 200) {
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.applyData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
selApply(val) {
console.log(val)
},
// 添加申请人
addApply() {
this.applyIds.push({ dept: [], user: [], applyData: []})
},
// 删除
deleteClick1(item, index) {
console.log(item, index)
if (this.applyIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.applyIds.splice(index, 1)
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
//文件上传成功时
handlePhotoSuccess(res, file, file_list) {
console.log(res, file, file_list)
if (res.status == 200) {
this.add_params.logo = res.data.data.url
}
},
//点击文件列表中已上传的文件时
handlePhotoPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
//文件列表移除
handlePhotoRemove(file, fileList) {
this.add_params.logo = ''
},
//文件超出个数限制
handleExceed(files, fileList) {
const fileLen = files.length
const listLen = fileList.length
if (fileLen > 1 || listLen >= 1) {
this.$message({
message: '只能上传一张logo图片!',
type: 'warning'
})
return false
}
},
// 修改负责人
changeAdmin(val) {
this.add_params.admin_ids = val.join(',')
},
// 进度
changeProgress(val) {
this.add_params.progress = val
},
// 类目
changeCategory(val) {
this.add_params.product_category = val.join(',')
},
// 查询结果
changeSearch(val) {
this.add_params.search_result = val
},
// 申请结果
changeApply(val) {
this.add_params.apply_result = val
},
// 申请时间
changeApplyTime(val) {
this.add_params.apply_time = val
},
changePublishTime(val) {
this.add_params.publish_time = val
},
changeRenewalsTime(val) {
this.add_params.renewals_time = val
},
// 修改价格
changePrice(val) {
this.form.price = val
this.add_params.price = val
// 数字,小数验证
const regu = '^[0-9]+([.]{1}[0-9]+){0,1}$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入数字/小数!'
})
this.form.price = ''
this.add_params.price = ''
}
this.calculation(this.form.price, this.add_params.num)
},
// 修改数量
changeNum(val) {
this.form.num = val
this.add_params.num = val
// 正整数验证
const regu = '^[0-9]+$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入正整数!'
})
this.form.num = ''
this.add_params.num = ''
}
this.calculation(this.add_params.price, this.form.num)
},
// 计算合计费用
calculation(price, num) {
price = Number(price)
num = Number(num)
let total_price = 0
total_price = (price*num).toFixed(2)
console.log(total_price)
this.form.total_price = total_price
this.add_params.total_price = total_price
},
//提交
submitClick(form) {
// 负责人
let admin_ids = []
let apply_man = []
this.adminIds.forEach(item => {
admin_ids.push({dept: item.dept, user: item.user})
})
this.add_params.admin_ids = JSON.stringify(admin_ids)
// 申请人
this.applyIds.forEach(item => {
apply_man.push({dept: item.dept, user: item.user})
})
this.add_params.apply_man = JSON.stringify(apply_man)
this.add_params.name = this.form.name
this.add_params.register_country = this.form.register_country
this.add_params.org_ids = this.form.org_ids
console.log(this.add_params)
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message({
type: 'error',
message: '信息填写不完整!'
})
return false
} else {
this.$http.post('brand/save', this.add_params ).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.resetData()
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/PIP/trademark'
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
})
},
resetData(){
this.fileList = []
this.adminIds = [
{
dept:[],
user:[],
adminData: []
}
],
this.applyIds = [
{
dept:[],
user:[],
applyData: []
}
],
this.form = {
admin_ids: "",
apply_result: '',
apply_time: "",
id: '',
logo: "",
name: "",
num: '',
org_ids: "",
price: "",
product_category: "",
progress: '',
publish_time: "",
register_country: "",
renewals_time: "",
search_result: '',
total_price: ""
}
this.add_params = {
admin_ids: "",
apply_result: '',
apply_time: "",
id: '',
logo: "",
name: "",
num: 0,
org_ids: "",
price: 0,
product_category: "",
progress: '',
publish_time: "",
register_country: "",
renewals_time: "",
search_result: '',
total_price: 0
}
}
}
}
</script>
<style scoped>
.basic_info{ border-bottom: 1px solid #dcdfe6;}
</style>

View File

@@ -0,0 +1,771 @@
<template>
<main>
<div class="bg_white m-20" style="margin-bottom: 70px;">
<div class="wrap text-black p-t-20 p-b-20 p-l-40 p-r-40">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" class="m-t-20" label-position="left">
<div class="basic_info">
<h3>基础信息</h3>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="编码" prop="id" required>
<el-input v-model="form.id" style="width: 60%;" disabled="true" placeholder=""></el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="商标名称" prop="name">
<el-input v-model="form.name" style="width: 60%;" placeholder="请输入商标名称"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="项目负责人" prop="" required>
<template v-for="(item, index) in adminIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择项目负责人" filterable @change="selAdmin">
<el-option v-for="(item1, index1) in item.adminData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addAdmin"></i>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="申请人" prop="" required>
<template v-for="(item, index) in applyIds" :key="index">
<el-cascader
v-model="item.dept"
:options="deptData1"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
}"
@change="changeDept1"
>
</el-cascader>
<el-select v-model="item.user" multiple placeholder="请选择申请人" filterable @change="selApply">
<el-option v-for="(item1, index1) in item.applyData" :key="index1" :label="item1.staff_name" :value="item1.staff_code"></el-option>
</el-select>
<i class="el-icon-delete m-l-10" @click="deleteClick1(item, index)"></i>
</template>
<i class="el-icon-circle-plus-outline m-l-10" @click="addApply"></i>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="注册国家" prop="register_country">
<el-input v-model="form.register_country" placeholder="多个国家间用“,”隔开" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="申请主体" prop="org_ids">
<el-input v-model="form.org_ids" placeholder="请输入公司名称" style="width: 60%;"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<el-form-item label="申请进度" prop="progress">
<el-select v-model="form.progress" placeholder="请选择申请进度" @change="changeProgress">
<el-option v-for="(item, index) in progress" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="产品使用类目" prop="product_category">
<el-select v-model="form.product_category" multiple placeholder="请选择产品使用类目" @change="changeCategory">
<el-option v-for="(item, index) in category" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="LOGO" prop="" required>
<el-upload
ref="upload"
:action="api_upload_url"
list-type="picture-card"
name="img"
:with-credentials = "true"
:on-success="handlePhotoSuccess"
:on-preview="handlePhotoPreview"
:limit="1"
:on-remove="handlePhotoRemove"
accept=".jpg,.png"
:on-exceed="handleExceed"
:file-list="fileList"
>
<el-button size="small" type="text"><i class="el-icon-plus"></i></el-button>
</el-upload>
<div class="el-upload__tip f_12 l_height_25">支持pngjpg格式, 上限1M</div>
<el-dialog v-model="dialogVisible">
<el-image width="100%" :src="dialogImageUrl" alt=""></el-image>
</el-dialog>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="others">
<el-row>
<el-col :span="12">
<h3>查询结果</h3>
<el-radio-group v-model="form.search_result" @change="changeSearch">
<el-radio v-for="(item, index) in query" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<h3>申请结果</h3>
<el-radio-group v-model="form.apply_result" @change="changeApply">
<el-radio v-for="(item, index) in result" :key="index" :label="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<h3>时间进度</h3>
<el-row>
<el-col :span="8">
<el-form-item label="申请时间" prop="apply_time">
<el-date-picker
v-model="form.apply_time"
type="date"
placeholder="请选择申请时间"
value-format="YYYY-MM-DD"
@change="changeApplyTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="公告时间">
<el-date-picker
v-model="form.publish_time"
type="date"
placeholder="请选择公告时间"
value-format="YYYY-MM-DD"
@change="changePublishTime">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="续费时间">
<el-date-picker
v-model="form.renewals_time"
type="date"
placeholder="请选择续费时间"
value-format="YYYY-MM-DD"
@change="changeRenewalsTime">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<h3>费用信息</h3>
<el-row>
<el-col :span="8">
<el-form-item label="单价" prop="">
<el-input v-model="form.price" style="width: 60%;" placeholder="仅限数字,支持小数" @change="changePrice"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="">
<el-input v-model="form.num" style="width: 60%;" placeholder="仅限正整数" @change="changeNum"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总计" prop="">
<el-input v-model="form.total_price" style="width: 60%;" placeholder="" disabled="true"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
</div>
<div class="bg_white m-t-10 p-l-20 p-r-20 p-t-10 p-b-10 text-black footer" style="width:100%;">
<el-button type="primary" class="search_button" @click="submitClick('form')">提交</el-button>
</div>
</main>
</template>
<script>
import { reactive } from 'vue';
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
id: '',
form: {},
rules: {
name: [
{
required: true,
message: '请输入商标名称',
trigger: 'blur',
}
],
progress: [
{
required: true,
message: '请选择申请进度',
trigger: 'change',
}
],
register_country: [
{
required: true,
message: '请输入注册国家',
trigger: 'blur',
}
],
org_ids: [
{
required: true,
message: '请输入公司名称',
trigger: 'blur',
}
],
product_category: [
{
required: true,
message: '请选择产品使用类目',
trigger: 'change',
}
],
apply_time: [
{
type: 'date',
required: true,
message: '请选择申请时间',
trigger: 'change',
}
]
},
adminIds: [],
applyIds: [],
dialogVisible: false,
dialogImageUrl: '',
// adminData: [],
progress: [],
category: [],
query: [],
result: [],
fileList: [],
edit_params: {
admin_ids: "",
apply_man: '',
apply_result: '',
apply_time: "",
id: '',
logo: "",
name: "",
num: 0,
org_ids: "",
price: "",
product_category: "",
progress: '',
publish_time: "",
register_country: "",
renewals_time: "",
search_result: '',
total_price: ""
},
deptData: [],
deptData1: [],
deptCodes: '',
deptCodes1: ''
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + '/admin/brand/upload'
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags
})
},
created() {
this.getListData()
this.getAdminData()
},
activated() {
this.id = this.$route.query.id
this.getDetail()
},
beforeRouteUpdate(to,from,next){
console.log(to,from)
this.id = to.query.id
if(to.fullPath!=from.fullPath){
this.getDetail()
next()
}
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
// 获取列表数据
getListData() {
this.$http.get('brand/constList').then(res => {
if (res.status == 200) {
const data = res.data.data
this.progress = data.progress
this.category = data.product_category
this.query = data.search_result
this.result = data.apply_result
}
})
},
// 获取项目负责人数据
getAdminData() {
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData = res.data.data
}
})
this.$http.get('brand/getAllDeptList').then(res => {
if (res.status == 200) {
this.deptData1 = res.data.data
}
})
},
// 设置禁用选项
setDisabled(data, data1) {
data.forEach(item => {
if (item.children) {
item.children.forEach(item1 => {
item1.disabled = false
if (item1.children) {
item1.children.forEach(item2 => {
item2.disabled = false
data1.forEach(ele => {
if (ele == item2.dept_code){
item2.disabled = true
}
})
})
} else {
data1.forEach(ele => {
if (ele == item1.dept_code){
item1.disabled = true
}
})
}
})
}
})
},
//选择项目负责人--部门数据
changeDept(val) {
this.deptCodes = val[val.length - 1]
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes }).then(res => {
if(res.status == 200) {
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes == item1) {
item.adminData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
selAdmin(val) {
console.log(val)
},
// 添加负责人
addAdmin() {
this.adminIds.push({ dept: [], user: [], adminData: []})
},
// 删除
deleteClick(item, index) {
console.log(item, index)
if (this.adminIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.adminIds.splice(index, 1)
// 获取需要禁用的项
let arr = []
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData, arr)
},
// 申请人 -- 部门数据
changeDept1(val) {
console.log(val)
this.deptCodes1 = val[val.length - 1]
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.user = []
}
})
})
this.$http.get('brand/getUserListByDeptCode', { dept_code: this.deptCodes1 }).then(res => {
if(res.status == 200) {
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (this.deptCodes1 == item1) {
item.applyData = res.data.data
}
})
})
}
})
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
selApply(val) {
console.log(val)
},
// 添加申请人
addApply() {
this.applyIds.push({ dept: [], user: [], applyData: []})
},
// 删除
deleteClick1(item, index) {
console.log(item, index)
if (this.applyIds.length <= 1) {
this.$message({
message: '请勿删除该数据!',
type: 'warning'
})
return false
}
this.applyIds.splice(index, 1)
// 获取需要禁用的项
let arr1 = []
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr1.push(item.dept[dep_len - 1])
}
})
// 调用禁用方法
this.setDisabled(this.deptData1, arr1)
},
// 数据回显
getDepartment(val, type) {
let deptCodes = ''
deptCodes = val[val.length - 1]
this.$http.get('brand/getUserListByDeptCode', { dept_code: deptCodes }).then(res => {
if(res.status == 200) {
if (type == 1) {
this.adminIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (deptCodes == item1) {
item.adminData = res.data.data
}
})
})
this.adminIds = reactive(this.adminIds)
} else {
this.applyIds.forEach((item, index) => {
item.dept.forEach(item1 => {
if (deptCodes == item1) {
item.applyData = res.data.data
}
})
})
this.applyIds = reactive(this.applyIds)
}
// 获取需要禁用的项
let arr = []
if (type == 1) {
this.adminIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
this.setDisabled(this.deptData, arr)
} else {
this.applyIds.forEach(item => {
let dep_len = item.dept.length
if (dep_len != 0) {
arr.push(item.dept[dep_len - 1])
}
})
this.setDisabled(this.deptData1, arr)
}
}
})
},
// 获取详情数据
getDetail() {
this.$http.get('brand/read/id', { id: this.id }).then(res => {
if (res.status == 200) {
this.form = res.data.data
this.form.search_result = Number(this.form.search_result)
this.form.apply_result = Number(this.form.apply_result)
this.fileList = [{name: 'logo', url: this.form.logo}]
this.dialogImageUrl = this.form.logo
if (this.form.product_category) {
const product_category = this.form.product_category.split(',')
let data = []
product_category.forEach(item => {
data.push(Number(item))
});
this.form.product_category = data
}
// 处理负责人的数据回显
const data = this.form.admin_ids
data.forEach(item => {
this.getDepartment(item.dept, 1)
})
this.adminIds = data
//申请人的数据回显
const data1 = this.form.apply_man
data1.forEach(item => {
this.getDepartment(item.dept, 2)
})
this.applyIds = data1
// 未做修改直接保存
let admin_ids = []
let apply_man = []
this.adminIds.forEach(item => {
admin_ids.push({dept: item.dept, user: item.user})
})
this.edit_params.admin_ids = JSON.stringify(admin_ids)
// 申请人
this.applyIds.forEach(item => {
apply_man.push({dept: item.dept, user: item.user})
})
this.edit_params.apply_man = JSON.stringify(apply_man)
this.edit_params = {
apply_result: this.form.apply_result,
apply_time: this.form.apply_time,
id: this.form.id,
logo: this.fileList[0].url,
name: this.form.name,
num: this.form.num,
org_ids: this.form.org_ids,
price: this.form.price,
product_category: this.form.product_category,
progress: this.form.progress,
publish_time: this.form.publish_time,
register_country: this.form.register_country,
renewals_time: this.form.renewals_time,
search_result: this.form.search_result,
total_price: this.form.total_price
}
if (this.edit_params.product_category) {
this.edit_params.product_category = this.edit_params.product_category.join(',')
}
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
//文件上传成功时
handlePhotoSuccess(res, file, file_list) {
console.log(res, file, file_list)
if (res.status == 200) {
this.edit_params.logo = res.data.data.url
}
},
//点击文件列表中已上传的文件时
handlePhotoPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
//文件列表移除
handlePhotoRemove(file, fileList) {
console.log(file, fileList)
this.edit_params.logo = ''
},
//文件超出个数限制
handleExceed(files, fileList) {
console.log(files, fileList)
const fileLen = files.length
const listLen = fileList.length
if (fileLen > 1 || listLen >= 1) {
this.$message({
message: '只能上传一张logo图片!',
type: 'warning'
})
return false
}
},
// 进度
changeProgress(val) {
this.edit_params.progress = val
},
// 类目
changeCategory(val) {
this.edit_params.product_category = val.join(',')
},
// 查询结果
changeSearch(val) {
this.edit_params.search_result = val
},
// 申请结果
changeApply(val) {
this.edit_params.apply_result = val
},
// 申请时间
changeApplyTime(val) {
this.edit_params.apply_time = val
},
changePublishTime(val) {
this.edit_params.publish_time = val
},
changeRenewalsTime(val) {
this.edit_params.renewals_time = val
},
// 修改价格
changePrice(val) {
this.form.price = val
this.add_params.price = val
// 数字,小数验证
const regu = '^[0-9]+([.]{1}[0-9]+){0,1}$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入数字/小数!'
})
this.form.price = ''
this.add_params.price = ''
}
this.calculation(this.form.price, this.add_params.num)
},
// 修改数量
changeNum(val) {
this.form.num = val
this.add_params.num = val
// 正整数验证
const regu = '^[0-9]+$'
const re = new RegExp(regu)
if (!re.test(val)) {
this.$message({
type: 'error',
message: '请输入正整数!'
})
this.form.num = ''
this.add_params.num = ''
}
this.calculation(this.add_params.price, this.form.num)
},
// 计算合计费用
calculation(price, num) {
price = Number(price)
num = Number(num)
let total_price = 0
total_price = (price*num).toFixed(2)
console.log(total_price)
this.form.total_price = total_price
this.edit_params.total_price = total_price
},
//提交
submitClick(form) {
// 负责人
let admin_ids = []
let apply_man = []
this.adminIds.forEach(item => {
admin_ids.push({dept: item.dept, user: item.user})
})
this.edit_params.admin_ids = JSON.stringify(admin_ids)
// 申请人
this.applyIds.forEach(item => {
apply_man.push({dept: item.dept, user: item.user})
})
this.edit_params.apply_man = JSON.stringify(apply_man)
this.edit_params.name = this.form.name
this.edit_params.register_country = this.form.register_country
this.edit_params.org_ids = this.form.org_ids
console.log(this.edit_params)
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message({
type: 'error',
message: '信息填写不完整!'
})
return false
} else {
this.$http.put('/brand/update/id', this.edit_params ).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.getDetail()
this.fileList = []
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/PIP/trademark'
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
})
}
}
}
</script>
<style scoped>
.basic_info{ border-bottom: 1px solid #dcdfe6;}
</style>

67
src/views/agv/agv.scss Normal file
View File

@@ -0,0 +1,67 @@
/**/
.m-16{margin: 16px;}
.p-16{padding: 16px;}
.m-t-16{ margin-top: 16px;}
.m-b-16{ margin-bottom: 16px;}
.m-l-16{ margin-left: 16px;}
.m-r-16{ margin-right: 16px;}
.m-r-8{ margin-right: 8px;}
/**/
.isGreen{
color: #00AA5B
}
.isYellow{
color: #FFAB00
}
.isBlue{
color: #4178D5
}
.isCyan{
color: #3CBFFF
}
.isRed{
color: #FF4747
}
.Cursor{
cursor: pointer;
}
.el-button+.el-button{
margin-left: 0!important;
}
.el-form-item{
margin-bottom: 10px!important;
}
:deep(.el-dialog__title){
font-weight: bold;
color: #303133;
}
:deep(.el-dialog__body){
padding-top: 16px!important;
padding-bottom: 16px!important;
}
.pagination {
text-align: right;
}
/**顶部图标**/
.Files{
background: url('../../assets/daochu.png');
width: 14px;
height: 14px;
display: block;
background-size: cover;
float: left;
margin-right: 5px;
}
::v-deep(.top-box .el-button--small) {
font-size: 14px;
}
::v-deep(.top-box .el-button:hover,.top-box .el-button:focus){
background: #ecf5ff;
color: #409eff;
}
::v-deep(.top-box .el-button--primary:focus, .top-box .el-button--primary:hover){
background: #ecf5ff;
color: #409eff;
}

373
src/views/agv/agvList.vue Normal file
View File

@@ -0,0 +1,373 @@
<template>
<main class="m-16">
<div class="wrap bg_white">
<div class="p-16">
<el-row class="top-box">
<el-col :span="4">
<el-button type="primary" class="m-r-16" size="small" @click="addAgv">
<i class="el-icon-circle-plus" style="margin-right:5px; font-size:14px;"></i>新增</el-button>
<el-button type="primary" plain size="small" @click="exportHandle"><i class="Files"></i>导出</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="80px" label-position="left" class="m-t-20">
<el-row :gutter="10">
<el-col :span="4">
<el-form-item label="AGV类型" prop="">
<el-select v-model="filter.type" placeholder="请选择AGV类型" @change="changeType">
<el-option label="全部" value="-1">全部</el-option>
<el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="AGV状态" prop="">
<el-select v-model="filter.status" placeholder="请选择AGV状态" @change="changeAGVStatus">
<el-option label="全部" value="-1">全部</el-option>
<el-option v-for="(item, index) in statusData" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="AGV编码" prop="">
<el-input v-model="filter.agv_code" v-on:keyup.enter="changeCode" clearable @clear="clearInput('agv_code')" placeholder="请输入AGV编码"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="AGV名称" prop="">
<el-input v-model="filter.agv_title" v-on:keyup.enter="changeName" clearable @clear="clearInput('agv_title')" placeholder="请输入AGV名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-checkbox v-model="is_status" @change="changeCheckbox" label="仅显示启用的AGV"></el-checkbox>
</el-col>
<el-col :span="4">
<el-button type="primary" size="small" class="m-r-16" plain @click="resetData()">重置</el-button>
<el-button type="primary" size="small" @click="searchClick">搜索</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-table :data="tableData" style="width: auto;" border :header-cell-style="header_style">
<el-table-column prop="agv_title" label="AGV名称" width="200" align="center" />
<el-table-column prop="agv_code" label="AGV编码" width="120" align="center" />
<el-table-column prop="type_name" label="AGV类型" width="310" align="center" />
<el-table-column prop="status" label="AGV状态" width="80" align="center">
<template #default="scope">
<span class="isGreen" v-if="scope.row.status == '0'">空闲</span>
<span class="isYellow" v-else-if="scope.row.status == '1'">任务中</span>
<span class="isRed" v-else>充电中</span>
</template>
</el-table-column>
<el-table-column prop="address_title" label="当前所在位置" width="200" align="center" />
<el-table-column prop="cart_name" label="当前承载料车" width="240" align="center" />
<el-table-column prop="task_code" label="当前任务" width="240" align="center" />
<el-table-column prop="is_status" label="是否启用" width="80" align="center">
<template #default="scope">
<el-switch v-model="scope.row.is_status" @change="changeStatus($event, scope.row.id)" :active-value="0" :inactive-value="1" active-color="#13ce66" inactive-color="#EDEFF4" />
</template>
</el-table-column>
<el-table-column prop="" label="操作" align="center">
<template #default="scope">
<span class="isBlue Cursor m-r-16" @click="editClick(scope.row.id)">编辑</span>
<span class="Cursor" @click="deleteClick(scope.row)">删除</span>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination m-t-16"
:current-page="filter.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-col>
</el-row>
</div>
</div>
<!--新增弹窗-->
<el-dialog
class="addDialog"
v-model="dialogAdd"
:title="dialogTitle"
width="348px"
:before-close="handleClose"
>
<el-form :model="addForm" label-width="80px" label-position="left">
<el-form-item label="AGV编码">
<el-input v-model="addForm.agv_code" placeholder="新增后自动生成" disabled></el-input>
</el-form-item>
<el-form-item label="AGV名称">
<el-input v-model="addForm.agv_title" placeholder="请输入AGV名称"></el-input>
</el-form-item>
<el-form-item label="AGV类型">
<el-select v-model="addForm.type" placeholder="请选择AGV状态">
<el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button class="m-r-16" size="small" @click="handleClose">取消</el-button>
<el-button type="primary" size="small" @click="comfirm">确认</el-button>
</span>
</template>
</el-dialog>
</main>
</template>
<script>
import { exportExcel } from '/src/utils/exportExcel.js'
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: '',
data() {
return {
dialogAdd: false,
dialogTitle: '添加AGV',
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
is_status: true,
filter: {
type: '-1',
status: '-1',
agv_code: '',
agv_title: '',
is_status: '0',
size: 10,
page: 1,
export: 0
},
total: 0,
currentPage: 1,
types: [
{
id: '0',
name: '潜伏式AGV'
}
],
statusData: [
{
id: '0',
name: '空闲'
},
{
id: '1',
name: '任务中'
},
{
id: '2',
name: '充电中'
}
],
tableData: [],
addForm: {
type: '',
agv_code: '',
agv_title: '',
dotype: ''
}
}
},
created() {
this.filter.is_status = this.is_status == true ? '0' : '-1'
},
activated() {
this.getDataList()
},
methods: {
// 列表数据
getDataList() {
this.$http.post('Agv/vehicleList', this.filter).then(res => {
if (res.status == 200) {
this.tableData = res.data.results
this.total = res.data.count_limit
}
})
},
clearInput(key) { //清空输入框
this.filter[`${key}`] = ''
this.getDataList()
},
// 搜索
searchClick() {
this.getDataList()
},
// 重置搜索条件
resetData() {
this.filter = {
type: '-1',
status: '-1',
agv_code: '',
agv_title: '',
is_status: '0',
size: 10,
page: 1
}
this.getDataList()
},
clearData() {
this.addForm = {
type: '',
agv_code: '',
agv_title: '',
dotype: ''
}
},
// 选择料车类型
changeType(val) {
this.filter.type = val
this.getDataList()
},
// 选择agv状态
changeAGVStatus(val) {
this.filter.status = val
this.getDataList()
},
// 搜索编码
changeCode() {
this.getDataList()
},
// 搜索名称
changeName() {
this.getDataList()
},
// 显示启用料车
changeCheckbox(val) {
this.filter.is_status = val == true ? '0' : '-1'
this.getDataList()
},
// 每页条数
changePageSize(val) {
this.filter.size = val
this.getDataList()
},
// 翻页
changePage(val) {
this.filter.page = val
this.getDataList()
},
// 添加
addAgv() {
this.dialogAdd = true
this.dialogTitle = '添加AGV'
this.addForm.dotype = 'add'
//生成编码
this.$http.post('Agv/addCode', { type: 'AGV' }).then(res => {
if (res.status == 200) {
this.addForm.agv_code = res.data.str_num
}
})
},
// 确认
comfirm() {
this.$http.post('Agv/editVehicle', this.addForm).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.dialogAdd = false
this.clearData()
this.getDataList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
// 修改禁用/启用状态
changeStatus(status, id) {
this.$http.post('Agv/editStatus', {type: 3, id: id, is_status: status}).then(res => {
if (res.status == 200) {
this.getDataList()
this.$message({
type: 'success',
message: res.message
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
// 编辑
editClick(id) {
this.dialogAdd = true
this.dialogTitle = '编辑AGV'
this.$http.post('Agv/detailInfo', {type: 3, id: id}).then(res => {
if (res.status == 200) {
let data = res.data.result
this.addForm = data
this.addForm = {
dotype : 'edit',
id: data.id,
agv_code: data.agv_code,
agv_title: data.agv_title,
type: data.type + '' //转为字符类型
}
}
})
},
handleClose() {
this.dialogAdd = false
this.clearData()
},
//删除
deleteClick(row) {
ElMessageBox.confirm('您确定要直接删除所选AGV吗该操作不可恢复请谨慎操作', '提示', {
type: 'warning',
confirmButtonText: '确定删除',
cancelButtonText: '我点错了',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.post('Agv/doDel', {id: row.id, type: 3}).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.getDataList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
//导出
exportHandle() {
this.filter.export = 1
let url = '/Agv/vehicleList'
exportExcel(url, this.filter)
}
}
}
</script>
<style lang="scss" scoped>
@import '@/views/agv/agv.scss';
</style>

383
src/views/agv/hopperCar.vue Normal file
View File

@@ -0,0 +1,383 @@
<template>
<main class="m-16">
<div class="wrap bg_white">
<div class="p-16">
<el-row class="top-box">
<el-col :span="4">
<el-button type="primary" plain class="m-r-16" size="small" @click="addHoppercar">
<i class="el-icon-circle-plus" style="margin-right:5px; font-size:14px;"></i>新增</el-button>
<el-button type="primary" size="small" plain @click="exportHandle"><i class="Files"></i>导出</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="80px" label-position="left" class="m-t-20">
<el-row :gutter="10">
<el-col :span="4">
<el-form-item label="料车类型" prop="">
<el-select v-model="filter.type" placeholder="请选择料车类型" @change="changeType">
<el-option label="全部" value="-1">全部</el-option>
<el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="料车状态" prop="">
<el-select v-model="filter.cart_status" placeholder="请选择料车状态" @change="changeLcStatus">
<el-option label="全部" value="-1">全部</el-option>
<el-option v-for="(item, index) in statusData" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="料车编码" prop="">
<el-input v-model="filter.cart_code" v-on:keyup.enter="changeCode" clearable @clear="clearInput('cart_code')" placeholder="请输入料车编码"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="料车名称" prop="">
<el-input v-model="filter.cart_title" v-on:keyup.enter="changeName" clearable @clear="clearInput('cart_title')" placeholder="请输入料车名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-checkbox v-model="is_status" @change="changeCheckbox" label="仅显示启用的料车"></el-checkbox>
</el-col>
<el-col :span="4">
<el-button type="primary" size="small" class="m-r-16" plain @click="resetData">重置</el-button>
<el-button type="primary" size="small" @click="searchClick">搜索</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-table :data="tableData" style="width: auto;" border :header-cell-style="header_style">
<el-table-column prop="cart_title" label="料车名称" width="200" align="center" />
<el-table-column prop="cart_code" label="料车编码" width="120" align="center" />
<el-table-column prop="type_name" label="料车类型" width="310" align="center" />
<el-table-column prop="order_by" label="优先级" width="80" align="center" />
<el-table-column prop="cart_status" label="料车状态" width="120" align="center">
<template #default="scope">
<span class="isGreen" v-if="scope.row.cart_status == '0'">空闲</span>
<span class="isYellow" v-else-if="scope.row.cart_status == '1'">任务中</span>
<span class="isCyan" v-else>已装载</span>
</template>
</el-table-column>
<el-table-column prop="address_title" label="当前所在位置" width="200" align="center" />
<el-table-column prop="agv_name" label="当前使用AGV" width="240" align="center" />
<el-table-column prop="is_status" label="是否启用" width="120" align="center">
<template #default="scope">
<el-switch v-model="scope.row.is_status" @change="changeStatus($event, scope.row.id)" :active-value="0" :inactive-value="1" active-color="#13ce66" inactive-color="#EDEFF4" />
</template>
</el-table-column>
<el-table-column prop="" label="操作" align="center">
<template #default="scope">
<span class="isBlue Cursor m-r-16" @click="editClick(scope.row.id)">编辑</span>
<span class="Cursor" @click="deleteClick(scope.row)">删除</span>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination m-t-16"
:current-page="filter.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-col>
</el-row>
</div>
</div>
<!--新增弹窗-->
<el-dialog
class="addDialog"
v-model="dialogAdd"
:title="dialogTitle"
width="348px"
:before-close="handleClose"
>
<el-form :model="addForm" label-width="80px" label-position="left">
<el-form-item label="料车编码">
<el-input v-model="addForm.cart_code" placeholder="新增后自动生成" :disabled="isDisable"></el-input>
</el-form-item>
<el-form-item label="料车名称">
<el-input v-model="addForm.cart_title" placeholder="请输入料车名称"></el-input>
</el-form-item>
<el-form-item label="料车类型">
<el-select v-model="addForm.type" placeholder="请选择料车状态">
<el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="优先顺序">
<el-input-number
v-model="addForm.order_by"
:min="1"
:max="10"
controls-position="right"
@change="handleChange"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button class="m-r-16" size="small" @click="handleClose">取消</el-button>
<el-button type="primary" size="small" @click="comfirm">确认</el-button>
</span>
</template>
</el-dialog>
</main>
</template>
<script>
import { exportExcel } from '/src/utils/exportExcel.js'
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: '',
data() {
return {
isDisable: false,
dialogAdd: false,
dialogTitle: '添加料车',
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
is_status: true,
filter: {
type: '-1',
cart_status: '-1',
cart_code: '',
cart_title: '',
is_status: '0',
size: 10,
page: 1,
export: 0
},
total: 0,
currentPage: 1,
types: [
{
id: '0',
name: '双层料车1.0x1.0米'
},
{
id: '1',
name: '单层料车1.0x1.0米'
}
],
statusData: [
{
id: '0',
name: '空闲'
},
{
id: '1',
name: '任务中'
},
{
id: '2',
name: '已装载'
}
],
tableData: [],
addForm: {
type: '',
order_by: '1',
cart_code: '',
cart_title: '',
dotype: ''
}
}
},
created() {
this.filter.is_status = this.is_status == true ? '0' : '-1'
},
activated() {
this.getDataList()
},
methods: {
// 列表数据
getDataList() {
this.$http.post('Agv/cartList', this.filter).then(res => {
if (res.status == 200) {
this.tableData = res.data.results
this.total = res.data.count_limit
}
})
},
clearInput(key) { //清空输入框
this.filter[`${key}`] = ''
this.getDataList()
},
// 搜索
searchClick() {
this.getDataList()
},
// 重置搜索条件
resetData() {
this.filter = {
type: '-1',
cart_status: '-1',
cart_code: '',
cart_title: '',
is_status: '0',
size: 10,
page: 1
}
this.getDataList()
},
clearData() {
this.addForm = {
type: '',
order_by: '1',
cart_code: '',
cart_title: '',
dotype: ''
}
},
// 选择料车类型
changeType(val) {
this.filter.type = val
this.getDataList()
},
// 选择料车状态
changeLcStatus(val) {
this.filter.cart_status = val
this.getDataList()
},
// 搜索编码
changeCode() {
this.getDataList()
},
// 搜索名称
changeName() {
this.getDataList()
},
// 显示启用料车
changeCheckbox(val) {
this.filter.is_status = val == true ? '0' : '-1'
this.getDataList()
},
// 新增
addHoppercar(){
this.dialogAdd = true
this.dialogTitle = '添加料车'
this.addForm.dotype = 'add'
this.isDisable = false
},
// 确认
comfirm() {
this.$http.post('Agv/editCart', this.addForm).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.dialogAdd = false
this.clearData()
this.getDataList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
// 修改禁用/启用状态
changeStatus(status, id) {
console.log(status, id)
this.$http.post('Agv/editStatus', {type: 2, id: id, is_status: status}).then(res => {
if (res.status == 200) {
this.getDataList()
this.$message({
type: 'success',
message: res.message
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
//编辑
editClick(id) {
this.dialogAdd = true
this.dialogTitle = '编辑料车'
this.isDisable = true
this.$http.post('Agv/detailInfo', {type: 2, id: id}).then(res => {
if (res.status == 200) {
let data = res.data.result
this.addForm = data
this.addForm = {
dotype : 'edit',
id: data.id,
order_by: data.order_by,
cart_code: data.cart_code,
cart_title: data.cart_title,
type: data.type + '' //转为字符类型
}
}
})
},
handleClose() {
this.dialogAdd = false
this.clearData()
},
// 每页条数
changePageSize(val) {
this.filter.size = val
this.getDataList()
},
// 翻页
changePage(val) {
this.filter.page = val
this.getDataList()
},
//删除
deleteClick(row) {
ElMessageBox.confirm('您确定要直接删除所选料车吗?该操作不可恢复,请谨慎操作!', '提示', {
type: 'warning',
confirmButtonText: '确定删除',
cancelButtonText: '我点错了',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.post('Agv/doDel', {id: row.id, type: 2} ).then(res => {
if (res.status == 200) {
this.getDataList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
//导出
exportHandle() {
this.filter.export = 1
let url = '/Agv/cartList'
exportExcel(url, this.filter)
}
}
}
</script>
<style lang="scss" scoped>
@import '@/views/agv/agv.scss';
</style>

541
src/views/agv/position.vue Normal file
View File

@@ -0,0 +1,541 @@
<template>
<main class="m-16">
<div class="wrap bg_white">
<div class="p-16">
<el-row class="top-box">
<el-col :span="4">
<el-button type="primary" class="m-r-16" size="small" @click="addHoppercar">
<i class="el-icon-circle-plus" style="margin-right:5px; font-size:14px;"></i>新增</el-button>
<el-button type="primary" size="small" plain @click="exportHandle">
<i class="Files"></i>导出</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="80px" label-position="left" class="m-t-20">
<el-row :gutter="10">
<el-col :span="4">
<el-form-item label="位置类型" prop="">
<el-select v-model="filter.type" placeholder="请选择位置类型" @change="changeType">
<el-option label="全部" value="-1">全部</el-option>
<el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="位置状态" prop="">
<el-select v-model="filter.status" placeholder="请选择位置状态" @change="changeSiteStatus">
<el-option v-for="(item, index) in statusData" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="位置编码" prop="">
<el-input v-model="filter.address_code" v-on:keyup.enter="changeCode" clearable @clear="clearInput('address_code')" placeholder="请输入位置编码"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="位置名称" prop="">
<el-input v-model="filter.address_title" v-on:keyup.enter="changeSiteName" clearable @clear="clearInput('address_title')" placeholder="请输入位置名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-checkbox v-model="is_status" label="仅显示启用的位置" @change="changeCheckbox"></el-checkbox>
</el-col>
<el-col :span="4">
<el-button type="primary" size="small" class="m-r-16" plain @click="resetData">重置</el-button>
<el-button type="primary" size="small" @click="searchClick">搜索</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-table :data="tableData" style="width: auto;" border :header-cell-style="header_style" :row-class-name="setClassName">
<el-table-column width="50" type="expand">
<template #default="scope">
<el-table :data="scope.row.cart_data_list" style="width: 350px; margin-left: 50px;" border :header-cell-style="header_style">
<el-table-column prop="cart_title" label="当前停放料车" width="150" align="center"></el-table-column>
<el-table-column prop="cart_status_name" label="料车状态" width="80" align="center"></el-table-column>
<el-table-column prop="" label="物料明细" width="" align="center">
<template #default="scope1">
<span class="isBlue" style="cursor: pointer;"
v-if="scope.row.type == 2 && scope1.row.cart_status == 2"
@click="details(scope1.row, scope.row.address_title)">查看明细</span>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column prop="address_title" label="位置名称" width="240" align="center" />
<el-table-column prop="address_code" label="位置编码" width="120" align="center" />
<el-table-column prop="type_name" label="位置类型" width="240" align="center" />
<el-table-column prop="order_by" label="优先级" width="80" align="center" />
<el-table-column prop="status" label="位置状态" width="80" align="center">
<template #default="scope">
<span class="isGreen" v-if="scope.row.status == 0">空闲</span>
<span class="isYellow" v-else>占用</span>
</template>
</el-table-column>
<el-table-column prop="is_empty_spot" label="空料车停放点" width="120" align="center">
<template #default="scope">
<span class="isGreen" v-if="scope.row.is_empty_spot == 0"></span>
<span class="isYellow" v-else></span>
</template>
</el-table-column>
<el-table-column prop="is_stock_total" label="加入库存统计" width="120" align="center">
<template #default="scope">
<span class="isGreen" v-if="scope.row.is_stock_total == 1"></span>
<span class="isYellow" v-else></span>
</template>
</el-table-column>
<el-table-column prop="cart_title" label="当前停放料车" width="200" align="center">
<template #default="scope">{{ computedFn(scope.row.cart_title) }}</template>
</el-table-column>
<el-table-column prop="cart_status" label="料车状态" width="80" align="center">
<template #default="scope">
<span class="isGreen" v-if="computedFn(scope.row.cart_status) == 0">空闲</span>
<span class="isYellow" v-else-if="computedFn(scope.row.cart_status) == 1">任务中</span>
<span class="isYellow" v-else-if="computedFn(scope.row.cart_status) == 2">已装载</span>
<span class="" v-else></span>
</template>
</el-table-column>
<!-- <el-table-column prop="" label="物料明细" width="120" align="center">
<template #default="scope">
<a href="#" @click="details(scope.row)" class="isBlue" v-if="scope.row.type == '7' && scope.row.cart_status == 2">查看明细</a>
</template>
</el-table-column> -->
<el-table-column prop="is_status" label="是否启用" width="80" align="center">
<template #default="scope">
<el-switch v-model="scope.row.is_status" @change="changeStatus($event, scope.row.id)" :active-value="0" :inactive-value="1" active-color="#13ce66" inactive-color="#EDEFF4" />
</template>
</el-table-column>
<el-table-column prop="" label="操作" align="center">
<template #default="scope">
<span class="isBlue Cursor m-r-16" @click="editClick(scope.row.id)">编辑</span>
<span class="Cursor" @click="deleteClick(scope.row)">删除</span>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination m-t-16"
:current-page="filter.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-col>
</el-row>
</div>
</div>
<!--新增弹窗-->
<el-dialog
class="addDialog"
v-model="dialogAdd"
:title="dialogTitle"
width="348px"
:before-close="handleClose"
>
<el-form :model="addForm" label-width="80px" label-position="left">
<el-form-item label="位置编码">
<el-input v-model="addForm.address_code" placeholder="请输入位置编码" :disabled="isDisable"></el-input>
</el-form-item>
<el-form-item label="位置名称">
<el-input v-model="addForm.address_title" placeholder="请输入位置名称"></el-input>
</el-form-item>
<el-form-item label="位置类型">
<el-select v-model="addForm.type" placeholder="请选择位置状态">
<el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="优先顺序">
<el-input-number
v-model="addForm.order_by"
:min="1"
:max="10"
controls-position="right"
@change="handleChange"
/>
</el-form-item>
<div class="">
<el-checkbox v-model="is_spots" @change="changeSpots">空料车停放点</el-checkbox>
<el-checkbox v-model="is_join" @change="changeJoin">加入库存统计</el-checkbox>
</div>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button class="m-r-16" size="small" @click="handleClose">取消</el-button>
<el-button type="primary" size="small" @click="comfirm">确认</el-button>
</span>
</template>
</el-dialog>
<!--物料明细-->
<el-dialog
v-model="dialogMate"
title="物料明细"
width="760px"
height="600px"
>
<el-row class="m-b-16">
<el-col :span="12">位置{{ address }}</el-col>
<el-col :span="12">料车{{ cart }}</el-col>
</el-row>
<el-table :data="materialData" style="width: auto;" max-height="500" border :header-cell-style="header_style">
<el-table-column prop="fnumber" label="物料编码" width="140" align="center" />
<el-table-column prop="sku" label="规格型号" width="200" align="left" />
<el-table-column prop="product_info" label="物料名称" width="200" align="center" />
<el-table-column prop="transport_num" label="库存数量" width="80" align="center" />
<el-table-column prop="amount" label="库存单位" align="center" />
</el-table>
</el-dialog>
</main>
</template>
<script>
import { exportExcel } from '/src/utils/exportExcel.js'
import axios from 'axios'
import { ElMessageBox } from 'element-plus'
export default {
name: '',
data() {
return {
isDisable: false,
dialogAdd: false,
dialogMate: false,
dialogTitle: '添加位置',
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
is_status: true,
filter: {
type: '-1', //-1为全部0半生产入库上料点/成品出库下料点1半成品入库下料点2成品出库上料点3半成品出库上料点4半成品出库下料点5生产入库上料点6成品仓7成品仓仓位8AGV充电位
status: '-1', //-1为全部0为空闲1为占用
address_code: '',
address_title: '',
is_status: '0', //-1为全部0为启用1为禁用
size: 10,
page: 1,
export: 0
},
total: 0,
currentPage: 1,
types: [{
id: '0',
name: '半生产入库上料点/成品出库下料点'
},
{
id: '1',
name: '半成品入库下料点'
},
{
id: '2',
name: '成品出库上料点'
},
{
id: '3',
name: '半成品出库上料点'
},
{
id: '4',
name: '半成品出库下料点'
},
{
id: '5',
name: '生产入库上料点'
},
{
id: '6',
name: '成品仓'
},
{
id: '7',
name: '成品仓仓位'
},
{
id: '8',
name: 'AGV充电位'
}
],
statusData: [
{
id: '-1',
name: '全部'
},
{
id: '0',
name: '空闲'
},
{
id: '1',
name: '占用'
}
],
tableData: [],
materialData: [],
is_spots: false,
is_join: false,
addForm: {
type: '',
order_by: '1',
address_code: '',
address_title: '',
is_empty_spot: '0',
is_stock_total: '1',
dotype: ''
},
address: '',
cart: ''
}
},
computed: {
computedFn() {
return function(data) {
return data == null ? '' : data.split(',')[0]
}
}
},
created() {
this.filter.is_status = this.is_status == true ? '0' : '-1'
},
activated() {
this.getDataList()
},
methods: {
// 列表数据
getDataList() {
this.$http.post('Agv/addressList', this.filter).then(res => {
if (res.status == 200) {
this.tableData = res.data.results
this.total = res.data.count_limit
}
})
},
setClassName({row, index}){
if (row.cart_data_list.length <= 1) {
return 'row-expand-cover'
}
},
clearInput(key) { //清空输入框
this.filter[`${key}`] = ''
this.getDataList()
},
// clearSelect(key) { //清空选择框
// this.filter[`${key}`] = '-1'
// this.getDataList()
// },
// 重置搜索条件
resetData() {
this.filter = {
type: '-1',
status: '-1',
address_code: '',
address_title: '',
is_status: '0',
size: 10,
page: 1
}
this.getDataList()
},
// 搜索
searchClick() {
this.getDataList()
},
// 每页条数
changePageSize(val) {
this.filter.size = val
this.getDataList()
},
// 翻页
changePage(val) {
this.filter.page = val
this.getDataList()
},
// 选择位置类型
changeType(val) {
this.filter.type = val
this.getDataList()
},
// 选择位置状态
changeSiteStatus(val) {
this.filter.status = val
this.getDataList()
},
// 搜索编码
changeCode() {
this.getDataList()
},
// 搜索位置名称
changeSiteName() {
this.getDataList()
},
// 显示启用料车
changeCheckbox(val) {
this.filter.is_status = val == true ? '0' : '-1'
this.getDataList()
},
// 新增
addHoppercar(){
this.dialogAdd = true
this.dialogTitle = '添加位置'
this.addForm.dotype = 'add'
this.isDisable = false
//生成编码
// this.$http.post('Agv/addCode', { type: 'WZ' }).then(res => {
// if (res.status == 200) {
// this.addForm.address_code = res.data.str_num
// }
// })
},
// 是否是空物料停放点0为是1为否
changeSpots(val) {
if (val == true) {
this.addForm.is_empty_spot = '0'
} else {
this.addForm.is_empty_spot = '1'
}
},
// 是否加入库存统计0为否1为加入
changeJoin(val) {
if (val == true) {
this.addForm.is_stock_total = '1'
} else {
this.addForm.is_stock_total = '0'
}
},
// 确定
comfirm() {
this.$http.post('Agv/editAddress', this.addForm).then(res => {
if (res.status == 200) {
this.$message({
type: 'success',
message: res.message
})
this.dialogAdd = false
this.resetForm()
this.getDataList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
resetForm() {
this.addForm = {
type: '',
order_by: '1',
address_code: '',
address_title: '',
is_empty_spot: '0',
is_stock_total: '1',
dotype: ''
}
},
handleClose() {
this.resetForm()
this.dialogAdd = false
this.dialogMate = false
},
// 修改禁用/启用状态
changeStatus(status, id) {
this.$http.post('Agv/editStatus', {type: 1, id: id, is_status: status}).then(res => {
if (res.status == 200) {
this.getDataList()
this.$message({
type: 'success',
message: res.message
})
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
},
// 物料明细
details(row, address_title) {
let code = row.cart_code
this.address = address_title
this.cart = row.cart_title
this.dialogMate = true
this.$http.post('Agv/productList', {cart_code: code}).then(res => {
if (res.status == 200) {
this.materialData = res.data.results
}
})
},
//编辑
editClick(id) {
this.dialogAdd = true
this.dialogTitle = '编辑位置'
this.isDisable = true
this.$http.post('Agv/detailInfo', {type: 1, id: id}).then(res => {
if (res.status == 200) {
let data = res.data.result
this.addForm = data
this.is_spots = data.is_empty_spot == '0' ? true : false
this.is_join = data.is_stock_total == '1' ? true : false
this.addForm = {
dotype : 'edit',
id: data.id,
order_by: data.order_by,
address_code: data.address_code,
address_title: data.address_title,
is_empty_spot: this.is_spots == true ? '0' : '1',
is_stock_total: this.is_join == true ? '1' : '0',
type: data.type + '' //转为字符类型
}
}
})
},
//删除
deleteClick(row) {
ElMessageBox.confirm('您确定要直接删除所选位置吗?该操作不可恢复,请谨慎操作!', '提示', {
type: 'warning',
confirmButtonText: '确定删除',
cancelButtonText: '我点错了',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.post('Agv/doDel', {id: row.id, type: 1} ).then(res => {
if (res.status == 200) {
this.getDataList()
} else {
this.$message({
type: 'error',
message: res.message
})
}
})
}
done()
}
})
},
//导出
exportHandle() {
this.filter.export = 1
let url = '/Agv/addressList'
exportExcel(url, this.filter)
}
},
}
</script>
<style lang="scss" scoped>
@import '@/views/agv/agv.scss';
::v-deep(.el-table .row-expand-cover .cell .el-table__expand-icon ){
display: none;
}
</style>

View File

@@ -0,0 +1,206 @@
<template>
<main class="m-16">
<div class="wrap bg_white">
<div class="p-16">
<el-row class="top-box">
<el-col :span="4">
<el-button type="primary" plain size="small" @click="exportClick"><i class="Files"></i>导出</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form ref="form" :model="filter" label-width="60px" label-position="left" class="m-t-20">
<el-row :gutter="10">
<el-col :span="4">
<el-form-item label="料车" prop="">
<el-select v-model="filter.cart_code" filterable placeholder="请输入/选择料车" @change="changeCart">
<el-option v-for="(item, index) in AGVlist" :key="index" :label="item.cart_title" :value="item.cart_code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="位置" prop="">
<el-select v-model="filter.end_address_code" filterable placeholder="请输入/选择位置" @change="changeAddress">
<el-option v-for="(item, index) in siteList" :key="index" :label="item.address_title" :value="item.address_code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="物料" prop="">
<el-input v-model="filter.keyword" placeholder="请输入物料编码/名称/SKU" v-on:keyup.enter="searchMaterail"></el-input>
</el-form-item>
</el-col>
<el-col :span="4" :offset='1'>
<el-button type="primary" size="small" class="m-r-16" plain @click="resetClick">重置</el-button>
<el-button type="primary" size="small" @click="searchClick">搜索</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-table :data="tableData" style="width: auto;" border :header-cell-style="header_style">
<el-table-column prop="fnumber" label="物料编码" width="240" align="center" />
<el-table-column prop="sku" label="规格型号SKU" width="320" align="center" />
<el-table-column prop="product_info" label="物料名称" width="320" align="center" />
<el-table-column prop="transport_num" label="库存数量" width="120" align="center"></el-table-column>
<el-table-column prop="amount" label="库存单位" width="120" align="center" />
<el-table-column prop="agv_address_name" label="位置" width="240" align="center" />
<el-table-column prop="cart_code" label="料车" align="center" />
</el-table>
<el-pagination
class="pagination m-t-16"
:current-page="filter.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</el-col>
</el-row>
</div>
</div>
</main>
</template>
<script>
import { exportExcel } from '/src/utils/exportExcel.js'
import axios from 'axios'
export default {
name: '',
data() {
return {
header_style: {
'background-color': '#F5F7FA',
'color': '#606266',
'fontSize': '14px',
'fontWeight': '600',
'textAlign':'center',
},
filter: {
size: 10,
page: 1,
export: 0,
cart_code: '',
end_address_code: '',
keyword: ''
},
total: 0,
currentPage: 1,
AGVlist: [],
siteList: [],
tableData: [
{
id: 1,
name: '潜伏式AGV001',
code: 'WZ001',
type: '生产入库上料点上料点',
num: 1,
unit: 'PCS',
position: '半成品入库下料点2',
hopper: '双层料车1.0x1.0米-01'
},
{
id: 2,
name: '潜伏式AGV001',
code: 'WZ001',
type: '生产入库上料点上料点',
num: 1,
unit: 'PCS',
position: '半成品入库下料点2',
hopper: '双层料车1.0x1.0米-01'
},
{
id: 3,
name: '潜伏式AGV001',
code: 'WZ001',
type: '生产入库上料点上料点',
num: 1,
unit: 'PCS',
position: '半成品入库下料点2',
hopper: '双层料车1.0x1.0米-01'
}
],
}
},
created() {
this.getDataList()
this.getAgvlist()
},
methods: {
//列表数据
getDataList() {
this.$http.post('Agv/stockList', this.filter).then(res => {
console.log(res)
if (res.status == 200) {
this.tableData = res.data.results
this.total = res.data.count_limit
}
})
},
// 每页条数
changePageSize(val) {
this.filter.size = val
this.getDataList()
},
// 翻页
changePage(val) {
this.filter.page = val
this.getDataList()
},
//搜索
searchClick() {
this.getDataList()
},
//重置
resetClick() {
this.filter = {
size: 10,
page: 1,
export: 0,
cart_code: '',
end_address_code: '',
keyword: ''
}
this.getDataList()
},
//选择料车
changeCart(val) {
this.filter.cart_code = val
this.getDataList()
},
//选择位置
changeAddress(val) {
this.filter.end_address_code = val
this.getDataList()
},
//查询物料
searchMaterail() {
this.getDataList()
},
//料车列表数据
getAgvlist() {
this.$http.post('Agv/addressCart').then(res => {
if (res.status == 200) {
this.AGVlist = res.data.agv_cart
this.siteList = res.data.agv_address
}
})
},
//导出
exportClick() {
this.filter.export = 1
let url = '/Agv/stockList'
exportExcel(url, this.filter)
}
}
}
</script>
<style lang="scss" scoped>
@import '@/views/agv/agv.scss';
</style>

312
src/views/agv/taskList.vue Normal file
View File

@@ -0,0 +1,312 @@
<template>
<main class="m-16">
<div class="wrap bg_white">
<div class="p-16">
<el-row class="top-box">
<el-col :span="4">
<el-button type="primary" plain size="small" @click="exportHandle"><i class="Files"></i>导出</el-button>
</el-col>
</el-row>
<el-row class="m-t-16">
<el-col :span="24">
<vxe-table
border
ref="xTable"
show-overflow
:cell-style="cellStyle"
:filter-config="{showIcon: false}"
:scroll-x="{enabled: false}"
:data="tableData">
<vxe-colgroup title="任务编码" fixed="left">
<vxe-column field="task_code" width="150">
<template #header>
<el-input size="mini" v-model="filter.task_code" @keydown.enter.native="getDataList()"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="任务类型" fixed="left">
<vxe-column field="type_name" width="150">
<template #header>
<el-select v-model="filter.type" placeholder="" clearable filterable size="mini"
@clear="clear('type')">
<el-option v-for="(item, index) in taskTypeList" :key="index" :label="item.label" :value="item.value"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="任务状态" fixed="left">
<vxe-column field="status_name" width="150">
<template #header>
<el-select v-model="filter.status" placeholder="" clearable filterable size="mini"
@clear="clear('status')">
<el-option v-for="(item, index) in statusList" :key="index" :label="item.label" :value="item.value"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="料车">
<vxe-column field="cart_code_name" width="150">
<template #header>
<el-select v-model="filter.cart_code" placeholder="" clearable filterable size="mini"
@clear="clear('cart_code')">
<el-option v-for="(item, index) in hopperCarList" :key="index" :label="item.cart_title" :value="item.cart_code"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="AGV">
<vxe-column field="vehicle_code_name" width="150">
<template #header>
<el-select v-model="filter.vehicle_code" placeholder="" clearable filterable size="mini"
@clear="clear('vehicle_code')">
<el-option v-for="(item, index) in AGVList" :key="index" :label="item.agv_title" :value="item.agv_code"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="运输起点">
<vxe-column field="start_address_code_name" width="150">
<template #header>
<el-select v-model="filter.start_address_code" placeholder="" clearable filterable size="mini"
@clear="clear('start_address_code')">
<el-option v-for="(item, index) in addressList" :key="index" :label="item.address_title" :value="item.address_code"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="运输终点">
<vxe-column field="end_address_code_name" width="150">
<template #header>
<el-select v-model="filter.end_address_code" placeholder="" clearable filterable size="mini"
@clear="clear('end_address_code')">
<el-option v-for="(item, index) in addressList" :key="index" :label="item.address_title" :value="item.address_code"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="出入库类型">
<vxe-column field="chu_type_name" width="150">
<template #header>
<el-select v-model="filter.chu_type" placeholder="" clearable filterable size="mini"
@clear="clear('chu_type')">
<el-option v-for="(item, index) in warehouseList" :key="index" :label="item.label" :value="item.value"
@click="getDataList()"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="出入库单号">
<vxe-column field="product_sn" width="150">
<template #header>
<el-input size="mini" v-model="filter.product_sn" @keydown.enter.native="getDataList()"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="物料信息">
<vxe-column field="product_info" width="300">
<template #header>
<el-input size="mini" v-model="filter.sku" @keydown.enter.native="getDataList()"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-column field="ys_num" width="120" title="运输数量"></vxe-column>
<vxe-column field="amount" width="120" title="单位"></vxe-column>
<vxe-column field="create_author" width="120" title="创建人"></vxe-column>
<vxe-column field="addtime" width="150" title="创建时间"></vxe-column>
<vxe-column field="finishtime" width="150" title="完成时间"></vxe-column>
</vxe-table>
</el-col>
</el-row>
<el-pagination
class="pagination m-t-16"
:current-page="filter.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="changePageSize"
@current-change="changePage"
>
</el-pagination>
</div>
</div>
</main>
</template>
<script>
import { exportExcel } from '/src/utils/exportExcel.js'
import axios from 'axios'
export default {
name: '',
data() {
return {
filter: {
size: 10,
page: 1,
task_code: '',
type: '-1', //-1为全部0为半成品入库1为半成品出库2为生产入库3为成品出库4为手工运输5为运送空料车
status: '-2', //-2为全部-1为已取消0为待装卸1为运输中2为排队中3为已完成
cart_code: '',
vehicle_code: '',
start_address_code: '',
end_address_code: '',
product_sn: '',
sku: '',
chu_type: '-1', //-1为全部0为生产领料1为采购入库2为生产入库3为直接调拨4为分布式调出5为销售出库6为其他出库
export: '0'
},
total: 0,
currentPage: 1,
tableData: [],
taskTypeList: [
{
value: '-1',
label: '全部'
},
{
value: '0',
label: '半成品入库'
},
{
value: '1',
label: '半成品出库'
},
{
value: '2',
label: '生产入库'
},
{
value: '3',
label: '成品出库'
},
{
value: '4',
label: '手工运输'
},
{
value: '5',
label: '运送空料车'
}
],
statusList: [
{ label: '全部', value: '-2' },
{ label: '待装卸', value: '0' },
{ label: '运输中', value: '1' },
{ label: '排队中', value: '2' },
{ label: '已完成', value: '3' },
{ label: '已取消', value: '-1' }
],
hopperCarList: [],
AGVList: [],
warehouseList: [
{ label: '全部', value: '-1' },
{ label: '生产领料', value: '0' },
{ label: '采购入库', value: '1' },
{ label: '生产入库', value: '2' },
{ label: '直接调拨', value: '3' },
{ label: '分步式调出', value: '4' },
{ label: '销售出库', value: '5' },
{ label: '其他出库', value: '6' },
{ label: '手工任务', value: '7' }
],
addressList: []
}
},
created() {
this.getDropList()
this.getDataList()
},
methods: {
//下拉列表数据
getDropList() {
this.$http.post('Agv/addressCart').then(res => {
if (res.status == 200) {
console.log(res.data)
this.hopperCarList = res.data.agv_cart
this.AGVList = res.data.agv_vehicle
this.addressList = res.data.agv_address
//下拉数据添加全部选项
this.hopperCarList.unshift({ cart_title: '全部', cart_code: '' })
this.AGVList.unshift({ agv_title: '全部', agv_code: '' })
this.addressList.unshift({ address_title: '全部', address_code: '' })
}
})
},
getDataList() {
console.log(this.filter, 1111111)
this.$http.post('Agv/taskList', this.filter).then(res => {
if (res.status == 200) {
this.tableData = res.data.results
this.total = res.data.count_limit
}
})
},
clear (item) {
if (item == 'type') {
this.filter.type = '-1'
} else if (item == 'status') {
this.filter.status = '-2'
} else if (item == 'cart_code') {
this.filter.cart_code = ''
} else if (item == 'vehicle_code') {
this.filter.vehicle_code = ''
} else if (item == 'start_address_code') {
this.filter.start_address_code = ''
} else if (item == 'end_address_code') {
this.filter.end_address_code = ''
} else if (item == 'chu_type') {
this.filter.chu_type = '-1'
}
this.getDataList()
},
// 每页条数
changePageSize(val) {
this.filter.size = val
this.getDataList()
},
// 翻页
changePage(val) {
this.filter.page = val
this.getDataList()
},
// 状态样式
cellStyle ({ row, rowIndex, column }) {
if (column.property === 'status') {
if (row.status === 1) {
return {
color: '#4178D5'
}
} else if ( row.status === 2) {
return {
color: '#00AA5B'
}
} else if ( row.status === 3) {
return {
color: '#FFAB00'
}
} else {
return {
color: '#606266'
}
}
}
},
//导出
exportHandle() {
this.filter.export = 1
let url = '/Agv/taskList'
exportExcel(url, this.filter)
}
}
}
</script>
<style lang="scss" scoped>
@import '@/views/agv/agv.scss';
</style>

View File

@@ -0,0 +1,483 @@
<template>
<main>
<div class="wrap text-black gyszj">
<!--顶部搜索-->
<el-row class="bg_white searchBox">
<el-col :span="24" style="margin-top:20px">
<el-form ref="form" :model="filter" label-width="100px">
<el-row>
<el-col :span="6">
<el-form-item label="供应商" prop>
<el-input v-model="filter.supplier" placeholder="请输入单个供应商名称查询"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="采购订单号" prop>
<el-input v-model="filter.pur_order_sn" placeholder="仅支持单个采购订单号"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="销售订单号" prop>
<el-input v-model="filter.sale_order_sn" placeholder="仅支持单个销售订单号"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="送货单号" prop>
<el-input v-model="filter.delivery_order_sn" placeholder="仅支持单个送货单号"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="sku/产品型号" prop>
<el-input v-model="filter.sku" placeholder="搜索多个sku时用逗号隔开"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="检测状态" prop>
<el-select v-model="filter.status" placeholder="请选择检测状态">
<el-option label="全部" value="-1"></el-option>
<el-option label="已检测" value="1"></el-option>
<el-option label="未检测" value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4" :offset="2" style="display: flex; align-items: center;">
<el-button type="primary" size="mini" @click="searchClick">搜索</el-button>
<el-button type="primary" size="mini" @click="reset">重置</el-button>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<!--table-->
<el-row class="bg_white">
<el-col :span="24">
<el-row class="m-t-10">
<el-col :span="6" class="m-l-40">
<el-button type="primary" @click="makeSure(1)" size="mini">确认</el-button>
<el-button type="primary" @click="makeSure(0)" size="mini">反确认</el-button>
<el-button type="primary" size="mini">
<el-upload
:action="api_upload_url"
:with-credentials="true"
:on-success="function (res, file, file_list) {return manyhandleSuccess(res, file, file_list)}"
:show-file-list="false"
name="file"
ref="upload"
v-loading.fullscreen.lock="loading"
:beforeUpload="manyhandleChange"
>
<span class="text_blue Cursor" style="color:white">批量上传</span>
</el-upload>
</el-button>
<el-button type="primary" @click="manydelet()" size="mini">批量删除</el-button>
</el-col>
</el-row>
<el-table
class="m-20"
:data="tableData"
style="margin-bottom: 10px;padding-right: 40px;"
border
height="620"
ref="multipleTable"
:header-cell-style="header_style"
@selection-change="handleSelectionChange"
:row-key="getRowKeys"
>
<el-table-column type="selection" :reserve-selection="true" width="55" align="center"></el-table-column>
<el-table-column fixed prop="sale_order_sn" label="销售订单号" width="220" />
<el-table-column fixed prop="pur_order_sn" label="采购订单号" width="220" />
<el-table-column prop="delivery_order_sn" label="送货单号" width="150" fixed align="center" />
<el-table-column prop="source" label="来源系统" width="180" />
<el-table-column prop="supplier" label="供应商/生产厂名" width="220" />
<el-table-column prop="sku" label="sku/产品型号" width="220" />
<el-table-column prop="name" label="物料名称" width="250" />
<el-table-column prop="check_status" label="检测状态" width="120" align="center" />
<el-table-column prop label="检测报告" width="220" align="center">
<template #default="scope">
<el-upload
v-if="!scope.row.report_url"
:action="api_upload_url"
:with-credentials="true"
:on-success="function (res, file, file_list) {return handleSuccess(res, file, file_list, scope.row)}"
:show-file-list="false"
name="file"
ref="upload"
v-loading.fullscreen.lock="loading"
:beforeUpload="handleChange"
>
<span class="text_blue Cursor m-r-10">上传</span>
</el-upload>
<div v-else>
<span @click="downloadTemplate(scope.row)" class="text_blue Cursor m-r-10">下载</span>
<span @click="deleteFile(scope.row, scope.$index)" class="text_blue Cursor">删除</span>
</div>
</template>
</el-table-column>
<el-table-column prop="confirm_status" label="确认状态" />
<el-table-column prop="num" label="送检数量(pcs)" width="180" align="center" />
<el-table-column prop="depot" label="送货仓库" width="220" align="center" />
<el-table-column prop="supplier_addr" label="供应商地址" width="220" />
<el-table-column prop="contact_mobile" label="联络人/电话号码" width="220" />
<el-table-column prop="scheck_date" label="送检日期" width="180" align="center" />
<el-table-column prop="check_date" label="检测日期" width="180" align="center" />
<el-table-column prop="check_user" label="检测人" align="center" />
<el-table-column prop="confirm_name" label="确认人" align="center" />
<el-table-column prop="remark" label="备注" width="300">
<template #default="scope">
<el-input v-model="scope.row.remark" @blur="remarkChange($event,scope.row)" maxlength="80"></el-input>
</template>
</el-table-column>
</el-table>
<el-row style="margin-bottom: 10px;float: right;">
<el-pagination
@size-change="changePageSize"
@current-change="changePage"
:current-page="filter.page"
:page-sizes="[50, 100, 200, 300]"
:page-size="filter.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</main>
</template>
<script>
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
export default {
name: 'copyRight',
data() {
return {
loading: false,
api_upload_url: '',
fileList: [], //上传的文件列表
header_style: {
'background-color': '#F5F7FA',
color: '#606266',
fontSize: '14px',
fontWeight: '600',
textAlign: 'center'
},
form: {},
tableData: [],
currentPage: 1,
total: 0,
filter: {
page: 1,
size: 50,
supplier: '',
pur_order_sn: '',
sale_order_sn: '',
delivery_order_sn: '',
sku: '',
status: '-1'
},
select_number: '', //表格select选中的条数
select_Id: [], //表格select复选框选中的id
multipleSelection: []
}
},
computed: {
api_upload_url() {
return process.env.VUE_APP_API_BASEURL + 'admin/Upload/file'
}
},
activated() {
this.getList()
},
methods: {
// 批量删除
manydelet() {
if (this.select_Id && this.select_Id.length > 0) {
ElMessageBox.confirm('你是否确定将所选行中的质检报告删除?', '提示', {
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
this.$http.get('qorder/delete_report?ids=' + this.select_Id).then(res => {
if (res.errno == 200) {
this.$message.success('删除成功')
this.$refs.multipleTable.clearSelection()
this.getList()
}
})
}
done()
}
})
} else {
this.$message({
message: '请先选择需要删除报告的质检单',
type: 'warning'
})
}
},
getRowKeys(row) {
//记录每行的key值
return row.id
},
// 修改备注
remarkChange(val, item) {
this.$http.post('qorder/edit', { id: item.id, remark: item.remark }).then(res => {
if (res.errno === 200) {
this.getList()
}
})
},
deleteFile(item) {
this.$confirm('确认删除该质检报告?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http.get('/qorder/delete_report', { id: item.id }).then(res => {
if (res.errno == 200)
this.$message({
type: 'success',
message: '删除成功!'
})
this.getList()
})
})
},
// 批量上传
manyhandleSuccess(res, file, file_list) {
this.loading = true
const ids = []
this.multipleSelection.forEach((it, index) => {
ids.push(it.id)
})
if (res.status == 200) {
this.$http.post('qorder/upload_report', { ids: ids.join(), report_url: res.data.imgpath }).then(ress => {
if (ress.errno == 200) {
this.getList()
this.$message({
type: 'success',
message: ress.errmsg
})
this.$refs.multipleTable.clearSelection()
} else {
this.$message({
type: 'error',
message: ress.errmsg
})
}
this.loading = false
})
} else {
this.loading = false
file_list.splice(file_list.length - 1, 1)
this.$message({
type: 'error',
message: res.errmsg
})
}
},
//上传
handleSuccess(res, file, file_list, item) {
this.loading = true
if (res.status == 200) {
this.$http.post('qorder/upload_report', { id: item.id, report_url: res.data.imgpath }).then(ress => {
if (ress.errno == 200) {
this.getList()
this.$message({
type: 'success',
message: ress.errmsg
})
} else {
this.$message({
type: 'error',
message: ress.errmsg
})
}
this.loading = false
})
} else {
this.loading = false
file_list.splice(file_list.length - 1, 1)
this.$message({
type: 'error',
message: res.errmsg
})
}
},
//批量上传文件限制
handleChange(file) {
if (this.multipleSelection.length === 0) {
this.$message({
message: '请先选择需要上传报告的质检单',
type: 'warning'
})
this.loading = false
return false
}
this.loading = true
const isLt2M = file.size / 1024 / 1024 < 10
if (!isLt2M) {
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
this.loading = false
}
return isLt2M
},
//上传文件限制
handleChange(file) {
this.loading = true
const isLt2M = file.size / 1024 / 1024 < 10
if (!isLt2M) {
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
this.loading = false
}
return isLt2M
},
// 勾选
handleSelectionChange(rows) {
this.multipleSelection = rows
if (rows.length === 1 && Object.keys(this.multipleSelection[0]).length == 0) {
this.select_number = 0
} else {
this.select_number = this.multipleSelection.length
}
this.select_Id = []
if (rows) {
rows.forEach(row => {
if (row && (row.id || row.id == 0)) {
this.select_Id.push(row.id)
}
})
}
},
// 确认
makeSure(status) {
if (this.select_Id && this.select_Id.length > 0) {
//status--0反确认 1确认
this.$http.get('qorder/confirm', { ids: this.select_Id.join(','), status: status }).then(res => {
if (res.errno == 200) {
this.$message.success('确认成功')
this.$refs.multipleTable.clearSelection()
this.getList()
}
})
} else {
this.$message.warning('请先确认勾选,在操作!')
}
},
//搜索
searchClick() {
this.filter.page = 1
this.getList()
},
// 重置
reset() {
this.filter = {
page: 1,
size: 50,
supplier: '',
pur_order_sn: '',
sale_order_sn: '',
delivery_order_sn: '',
sku: '',
status: '-1'
}
this.isCopyright = true
this.getList()
},
//版权list
getList() {
this.$http.get('qorder/list', this.filter).then(res => {
if (res.errno == 200) {
this.tableData = res.data.data
this.total = res.data.total
}
})
},
// 改变每页请求条数
changePageSize(size) {
this.filter.size = size
this.getList()
},
// 翻页
changePage(page) {
this.filter.page = page
this.getList()
},
// 下载
downloadTemplate(data) {
this.$message({
type: 'success',
message: '正在下载,请稍后...'
})
let url = ''
if (data == '') {
url = this.url
} else {
url = data.report_url
}
axios
.get(url, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
})
.then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const url_arr = res.config.url.split('/')
const nameStr = decodeURI(url_arr[url_arr.length - 1])
console.log(nameStr)
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
}
}
}
</script>
<style scoped>
::v-deep(.gyszj .el-input__inner) {
height: 30px;
}
::v-deep(.gyszj .el-form-item) {
margin-bottom: 5px;
}
::v-deep(.el-form-item__label, .el-form-item__label) {
font-size: 12px;
}
::v-deep(.gyszj .el-table .el-table__cell) {
padding: 0;
font-size: 12px;
}
::v-deep(.gyszj .el-table) {
font-size: 12px;
}
.wrap {
width: auto;
}
.bg_white {
overflow: hidden;
}
</style>

850
src/views/index/index.vue Normal file
View File

@@ -0,0 +1,850 @@
<template>
<el-main class="bg_white">
<div class="m-t-10 table_90 border-r-10 text-black">
<el-row>
<el-col :span="8">
<!-- <el-button type="primary" size="mini" @click="getList(1)">搜索</el-button>
<el-button type="primary" size="mini" @click="reset()">重置</el-button>-->
<el-button type="primary" size="mini" @click="save">保存修改</el-button>
</el-col>
<el-col :span="16" class="text-r">
<el-button style="border: 0;padding: 0;">
<el-upload action :auto-upload="false" :multiple="false" :show-file-list="false" :on-change="uploadByJsqd"
:file-list="fileList">
<el-button type="primary" size="mini">导入</el-button>
</el-upload>
</el-button>
<el-button type="primary" size="mini" @click="batchExport">导出</el-button>
<el-button type="primary" size="mini" @click="clickLog">日志</el-button>
<el-button type="primary" size="mini" @click="synchronizeErp">同步ERP数据</el-button>
</el-col>
</el-row>
</div>
<!--表格-->
<div class="bg_white table_90 m-t-10 border-r-10 text-black f-12">
<vxe-table border resizable show-overflow ref="xTable" height="700" :scroll-x="{ enabled: false }"
:scroll-y="{ enabled: false }" :header-row-style="header_style" :data="tableData" :edit-config="editConfig">
<vxe-colgroup title="基本信息" header-align="center" fixed="left" resizable>
<!-- <vxe-colgroup title="品牌" header-align="center">
<vxe-column field="name" width="100">
<template #header>
<el-select v-model="brand_name" placeholder="" @change="selectSKU()" clearable filterable size="mini">
<el-option v-for="(option, index) in brand_list" :key="index"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>-->
<vxe-column field="picture" title="图片" width="80" header-align="center" align="center" class="position-r">
<template #default="{ row }">
<el-upload :action="api_upload_url" :with-credentials="true"
:on-success="function (res, file, file_list) { return handleSuccess(res, file, file_list, row) }"
:show-file-list="false" name="file" accept=".png, .jpg" :on-change="handleChange">
<img v-if="row.picture" :src="row.picture" class="avatar" @mousemove="enlarge($event, row)"
@mouseout="enlargeOut(row)" />
<el-icon v-else class="el-icon-plus">
<plus />
</el-icon>
<view v-show="row.enlargeImgShow" class="img-show position-f" v-if="enlargeImg" :style="top">
<img :src="enlargeImg" />
</view>
</el-upload>
</template>
</vxe-column>
<vxe-colgroup title="规格型号(sku)" header-align="center">
<vxe-column field="model" width="150">
<template #header>
<el-input size="mini" v-model="form_requst.model" @keydown.enter.native="getList(1)"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="产品名称" header-align="center">
<vxe-column field="name" width="120" header-align="center">
<template #header>
<el-input size="mini" v-model="form_requst.name" @keydown.enter.native="getList(1)"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="生命周期" header-align="center">
<vxe-column field="F_PAEZ_Combo2" width="100" header-align="center">
<template #header>
<el-select v-model="form_requst.F_PAEZ_Combo2" placeholder clearable filterable size="mini"
@clear="clear('F_PAEZ_Combo2')">
<el-option v-for="(item, index) in F_PAEZ_Combo2" :key="index" :label="item" :value="item"
@click="getList"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-colgroup title="产品分类" header-align="center">
<vxe-colgroup title="一级分类" header-align="center">
<vxe-column field="category_one" width="100">
<template #header>
<el-select v-model="form_requst.category_one" placeholder clearable filterable size="mini"
@clear="clear('category_one')" ref="select_one">
<el-option v-for="(item1, index) in category_one" :key="index" :label="item1" :value="item1"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="二级分类" header-align="center">
<vxe-column field="category_two" width="100">
<template #header>
<el-select v-model="form_requst.category_two" placeholder clearable filterable size="mini"
@clear="clear('category_two')">
<el-option v-for="(item2, index) in category_two" :key="index" :label="item2" :value="item2"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="三级分类" header-align="center">
<vxe-column field="category_three" width="100">
<template #header>
<el-select v-model="form_requst.category_three" placeholder clearable filterable size="mini"
@clear="clear('category_three')">
<el-option v-for="(item3, index) in category_three" :key="index" :label="item3" :value="item3"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-colgroup header-align="center">
<vxe-colgroup title="项目负责团队" header-align="center">
<vxe-column field="team_user" width="100" header-align="center">
<template #header>
<el-select v-model="form_requst.team_user" placeholder clearable filterable size="mini"
@clear="clear('team_user')">
<el-option v-for="(items, index) in opd_list" :key="index" :label="items" :value="items"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-column field="cost" title="物料成本价" width="80" header-align="center" align="right"
v-if="userInfo.isall == 1"></vxe-column>
<vxe-column field="factory_price" title="成本价" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.factory_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="agent_price" title="代理价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.agent_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="retail_price" title="零售指导价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.retail_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="minimum_activity_price" title="最低活动价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.minimum_activity_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="overseas_retail_price" title="海外零售指导价($)" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.overseas_retail_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="overseas_minimum_activity_price" title="海外零售最低活动价($)" width="60" header-align="center"
align="right" :edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.overseas_minimum_activity_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-colgroup title="产品成本构成" header-align="center" v-if="userInfo.isall == 1">
<vxe-column field="clinker_cost" title="结构/本体" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.clinker_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="metal_cost" title="电子" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.metal_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="electron_cost" title="电源" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.electron_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="wire_cost" title="线材" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.wire_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="accessories_cost" title="辅料/配件" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.accessories_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="packing_cost" title="包材" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.packing_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="process_cost" title="加工费" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.process_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="other_cost" title="硬盘/运费其他" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.other_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="auth_cost" title="模具费/认证费等费用" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.auth_cost" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-column field="moq" title="MOQ" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.moq" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="packing" title="包装方式" width="80" header-align="center"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.packing" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-colgroup title="产品尺寸重量mm/g" header-align="center">
<vxe-column field="FLENGTH" title="长" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FLENGTH" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FWIDTH" title="宽" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FWIDTH" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FHEIGHT" title="高" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FHEIGHT" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FNETWEIGHT" title="重量" width="120" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FNETWEIGHT" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="包装版本1" header-align="center">
<vxe-colgroup title="包装尺寸重量mm/g" header-align="center">
<vxe-column field="FPACKAGE1" title="包装版本名称" width="60" header-align="center"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FPACKAGE1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FLENGTHP1" title="长" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FLENGTHP1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FWIDTHP1" title="宽" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FWIDTHP1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FHEIGHTP1" title="高" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FHEIGHTP1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FNETWEIGHTP1" title="重量" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FNETWEIGHTP1" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="装箱信息(mm/Kg)" header-align="center">
<vxe-column field="FQtyC1" title="数量" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FQtyC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FLENGTHC1" title="长" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FLENGTHC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FWIDTHC1" title="宽" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FWIDTHC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FHEIGHTC1" title="高" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FHEIGHTC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FNETWEIGHTC1" title="净重" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FNETWEIGHTC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FGROSSWEIGHTC1" title="毛重" width="120" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FGROSSWEIGHTC1" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-column field="FITEMPPROPERTY" title="物料属性" width="80" header-align="center" align="right"></vxe-column>
<vxe-column field="bom_version" title="BOM版本" width="140" header-align="center" align="right"></vxe-column>
<vxe-column field="remark1" title="绩效提成经营分析品线(一级)" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.remark1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="remark2" title="绩效提成经营分析品线(二级)" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.remark2" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="remark3" title="业绩/回款统计品线" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.remark3" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="line" title="交付管理品线" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.line" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="is_fm" title="是否闪存" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.is_fm" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="edit_time" title="上次更新" width="120" header-align="center" align="right"></vxe-column>
</vxe-table>
<el-pagination :current-page="form_requst.page" :page-sizes="[10, 20, 30]" :page-size="form_requst.size"
layout="total, sizes, prev, pager, next, jumper" :total="count" class="m-t-10 m-b-20 table_90"
@size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
</div>
<!--价格修改-->
</el-main>
</template>
<script>
import { mapState } from 'vuex'
import { ElMessage, ElLoading } from 'element-plus'
import axios from 'axios'
export default {
data () {
return {
loading: null,
fileList: [], //上传的文件列表
header_style: {
'background-color': '#F5F7FA',
color: '#606266',
fontSize: '10px',
fontWeight: '600',
textAlign: 'center'
},
brand_list: [],
sku_list: [],
name_list: [],
F_PAEZ_Combo2: [],
one_cate_list: [],
two_cate_list: [],
three_cate_list: [],
is_211: [],
supplier_list: [],
form_requst: {
page: 1,
size: 20,
model: '',
name: '',
F_PAEZ_Combo2: '',
category_one: '',
category_two: '',
category_three: '',
team_user: '',
is_new: 0
},
model: '',
name: '',
F_PAEZ_Combo2: '',
category_one: '',
category_two: '',
category_three: '',
opd_list: '',
form_buy: '',
fast: '',
supplier: '',
count: 0,
tableData: null,
save_form: [],
add_form: {
id: '',
key: '',
value: ''
},
CostFinance: '',
listLoading: '',
old_value: '',
enlargeImgShow: false,
enlargeImg: '',
top: ''
}
},
computed: {
...mapState({
// 取出页面标签
userInfo: state => state.user.userInfo
}),
editConfig () {
if (this.userInfo.isall == 1) {
return { trigger: 'click', mode: 'cell' }
}
},
api_upload_url () {
return process.env.VUE_APP_API_BASEURL + 'admin/Upload/uploadImgDemo'
}
},
created () {
this.getList()
},
methods: {
enlarge (e, row) {
console.log(e)
this.enlargeImg = row.picture
row.enlargeImgShow = true
this.top = 'top:' + e.clientY + 'px'
},
enlargeOut (row) {
row.enlargeImgShow = false
this.enlargeImg = ''
},
//成本列表
getList (type) {
if (type == 1) {
this.form_requst.page = 1
}
this.listLoading = true
this.$http
.get('cost/list', this.form_requst)
.then(res => {
if (res.errno == 200) {
res.data.list.forEach((item, index) => {
item.enlargeImgShow = false
})
this.tableData = res.data.list
this.brand = res.data.brand
this.F_PAEZ_Combo2 = res.data.F_PAEZ_Combo2
this.category_one = res.data.category_one
this.category_two = res.data.category_two
this.category_three = res.data.category_three
this.supplier = res.data.supplier
this.count = res.data.count
this.form_buy = res.data.form_buy
this.fast = res.data.fast
this.opd_list = res.data.opd
this.tableData.forEach(item => {
item.is_show = 1
})
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
this.listLoading = false
})
},
//clear select
clear (item) {
if (item == 'F_PAEZ_Combo2') {
this.form_requst.F_PAEZ_Combo2 = ''
}
if (item == 'category_one') {
this.form_requst.category_one = ''
}
if (item == 'category_two') {
this.form_requst.category_two = ''
}
if (item == 'category_three') {
this.form_requst.category_three = ''
}
if (item == 'team_user') {
this.form_requst.team_user = ''
}
this.getList()
},
//重置
reset () {
this.form_requst = {
page: 1,
size: 20,
model: '',
name: '',
F_PAEZ_Combo2: '',
category_one: '',
category_two: '',
category_three: '',
team_user: ''
}
this.getList()
},
//分页
handleSizeChange (new_size) {
this.form_requst.size = new_size
this.getList()
},
handleCurrentChange (new_page) {
this.form_requst.page = new_page
this.getList()
},
tableRowClassName ({ row, rowIndex }) {
if (rowIndex == this.rowClassName) {
return this.classNameRow
}
return ''
},
//编辑
handleClick (index, row) {
this.rowClassName = index
this.classNameRow = 'current-row'
row.is_show = 0
this.buttonEdit = false
this.buttonSave = true
},
//保存修改
save () {
console.log(this.tableData, 'this.tableData')
this.$http
.post('cost/edit', this.tableData)
.then(res => {
if (res.errno == 200) {
ElMessage({
type: 'success',
message: res.errmsg
})
this.getList()
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
// listLoading.close()
})
},
//同步ERP
synchronizeErp () {
const listLoading = ElLoading.service({
lock: true,
text: '同步ERP可能需要几分钟请耐心等待...'
})
this.$http
.get('cost/geterpinfo?is_new=0')
.then(res => {
if (res.errno == 200) {
ElMessage({
type: 'success',
message: res.errmsg
})
this.getList()
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
listLoading.close()
})
},
//文件校验方法
beforeAvatarUpload (file) {
// 通过split方法和fileArr方法获取到文件的后缀名
let fileArr = file.name.split('.')
let suffix = fileArr[fileArr.length - 1]
//只能导入.xls和.xlsx文件
if (!/(xls|xlsx)/i.test(suffix)) {
this.$message('文件格式不正确')
this.loading.close()
return false
}
//不能导入大小超过2Mb的文件
if (file.size > 2 * 1024 * 1024) {
this.$message('文件过大请上传小于2MB的文件〜')
return false
}
return true
},
//文件发生改变就会触发的事件
uploadByJsqd (file) {
this.loading = this.$loading({
lock: true,
text: '此操作需要一段时间请耐心等待...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
//判断是否符合beforeAvatarUpload方法中的条件
if (this.beforeAvatarUpload(file)) {
this.fileList.name = file.name
this.fileList.url = ''
var formdata = new FormData()
formdata.append('file', file.raw)
this.$http.post('cost/import', formdata).then(res => {
if (res.errno == 200) {
this.$message({
message: '导入成功',
type: 'success'
})
this.getList() //调用表格方法,刷新页面
} else {
let str = ''
if (res.data.length > 0) {
res.data.forEach(it => {
str = str + '<span>' + it + '</span><br>'
})
}
this.$alert('<div style="max-height:450px;overflow:auto">' + res.errmsg + '</br>' + str + '</div>', '导入失败提示', {
confirmButtonText: '确定',
customClass: 'msgbox',
dangerouslyUseHTMLString: true
})
}
// 导出新老sku 导出预加载
this.loading.close()
})
}
},
//批量导出
batchExport () {
// this.batchExportShow = true
const listLoading = this.$loading({
lock: true,
text: '此操作需要一段时间请耐心等待...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
const apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
axios
.get(process.env.VUE_APP_API_BASEURL + apiVersion + '/' + '/cost/export?is_new=0&isall=' + this.userInfo.isall + '&model=' + this.form_requst.model + '&name=' + this.form_requst.name + '&F_PAEZ_Combo2=' + this.form_requst.F_PAEZ_Combo2 + '&category_one=' + this.form_requst.category_one + '&category_two=' + this.form_requst.category_two + '&category_three=' + this.form_requst.category_three + '&team_user=' + this.form_requst.team_user, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
})
.then(res => {
listLoading.close()
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const nameStr = decodeURI(escape(JSON.parse(res.headers['content-disposition'].split(';')[1].split('=')[1])))
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
},
//日志
clickLog () {
this.$router.push({
path: '/index/log'
})
},
//上传图片
handleSuccess (res, file, file_list, item) {
console.log(item, 'item')
if (res.status == 200) {
// ElMessage({
// type: 'success',
// message: res.message,
// })
item.picture = res.data.imgpath
const formQuery = {
id: item.id,
picture: item.picture
}
this.$http.post('cost/saveImg', formQuery).then(ress => {
if (ress.errno == 200) {
ElMessage({
type: 'success',
message: ress.errmsg
})
} else {
ElMessage({
type: 'error',
message: ress.errmsg
})
}
})
} else {
file_list.splice(file_list.length - 1, 1)
ElMessage({
type: 'error',
message: res.errmsg
})
}
},
//上传前色子
//上传文件限制
handleChange (file, fileList) {
const isLt5M = file.size / 1024 / 1024 < 1
if (!isLt5M) {
ElMessage({
type: 'error',
message: '上传文件大小不能超过 1MB'
})
file = null
fileList = []
this.$refs.upload.clearFiles() // 清除前端显示的文件列表
} else {
if (file.status === 'ready') {
this.uploadFile = file.raw
}
}
}
}
}
</script>
<style scoped>
/*新样式*/
.vxe-table--render-default {
font-size: 12px;
}
::v-deep(.vxe-header--column, .vxe-table--render-default) {
padding: 5px 0 !important;
}
::v-deep(.vxe-body--column) {
height: 32px !important;
}
::v-deep(.vxe-table--render-default .vxe-cell) {
padding-left: 2px;
padding-right: 2px;
}
.select-class {
z-index: 10 !important;
position: absolute;
left: 0;
top: 50%;
margin-top: -14px;
}
::v-deep(.el-upload-list--picture-card .el-upload-list__item) {
margin-bottom: 0px !important;
width: 40px !important;
height: 40px !important;
}
::v-deep(.el-upload-list__item),
::v-deep(.vxe-body--row) {
width: 40px !important;
height: 50px !important;
line-height: 40px !important;
}
::v-deep(.el-upload-list__item) {
position: absolute;
}
::v-deep(.avatar) {
width: 40px;
height: 40px;
padding-top: 5px;
padding-bottom: 5px;
}
::v-deep(.el-icon-plus) {
width: 40px;
height: 40px;
border-radius: 2px;
line-height: 40px;
border: 1px dashed rgba(0, 0, 0, 0.1);
}
.img-show {
width: 150px;
height: 150px;
border: 1px solid rgba(0, 0, 0, 0.1);
overflow: hidden;
z-index: 9;
background-color: #fff;
vertical-align: middle;
margin-top: -60px;
text-align: center;
}
.img-show img {
z-index: 10;
max-width: 150px;
vertical-align: middle;
}
::v-deep(.vxe-cell--title) {
font-size: 12px !important;
}
</style>

278
src/views/index/log.vue Normal file
View File

@@ -0,0 +1,278 @@
<template>
<el-main class="bg_white">
<div class="m-t-10 table_90 border-r-10 text-black f-12">
<el-row>
<el-col :span="8">
<el-button type="primary" size="mini" @click="getList(1)">搜索</el-button>
<el-button type="primary" size="mini" @click="reset()">重置</el-button>
</el-col>
<el-col :span="16" class="text-r">
<el-button type="primary" size="mini" @click="batchExport">导出</el-button>
</el-col>
</el-row>
</div>
<!--表格-->
<div class="m-t-10 table_90 p-b-20 border-r-10 text-black f-12">
<vxe-table border resizable show-overflow ref="xTable" height="700" :scroll-x="{ enabled: false }"
:scroll-y="{ enabled: false }" :header-cell-style="header_style" :data="tableData"
:edit-config="{ trigger: 'click', mode: 'cell' }">
<vxe-colgroup title="SKU" header-align="center">
<vxe-column field="model">
<template #header>
<el-input size="mini" v-model="form_requst.model" @keydown.enter.native="getList"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="产品名" header-align="center">
<vxe-column field="name" header-align="center">
<template #header>
<el-input size="mini" v-model="form_requst.name" @keydown.enter.native="getList"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="变更人" header-align="center">
<vxe-column field="user" header-align="center">
<template #header>
<el-input size="mini" v-model="form_requst.user" @keydown.enter.native="getList"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="变更时间" header-align="center">
<vxe-column field="edit_time" header-align="center" align="right">
<template #header>
<el-date-picker v-model="form_requst.edit_time" type="date" placeholder="请选择发货日期"
:disabledDate="pickerOptions" value-format="YYYY-MM-DD" size="mini" style="width: 100%"
@change="getList"></el-date-picker>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="变更对象" header-align="center">
<vxe-column field="type" header-align="center">
<template #header>
<el-select v-model="form_requst.type" placeholder clearable filterable size="mini" @clear="clear('type')">
<el-option v-for="(item, index) in typeList" :key="index" :label="item.name" :value="item.value"
@click="getList"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-column field="cost_old" title="变更前" header-align="center" align="right"></vxe-column>
<vxe-column field="cost_now" title="变更后" header-align="center" align="right"></vxe-column>
<vxe-column field="cost_change" title="前后差异" header-align="center" align="right">
<template #default="{ row }">
<span v-if="row.cost_change > 0" class="text-red">{{ row.cost_change }}</span>
<span v-else class="text-green">{{ row.cost_change }}</span>
</template>
</vxe-column>
<vxe-column field="range" title="变更幅度" header-align="center" align="right">
<template #default="{ row }">
<span v-if="row.range > 0" class="text-red">{{ row.range }} %</span>
<span v-else class="text-green">{{ row.range }} %</span>
</template>
</vxe-column>
<vxe-column field="content" title="变更内容" header-align="center" v-if="userInfo.isall == 1"></vxe-column>
</vxe-table>
<el-pagination :current-page="form_requst.page" :page-sizes="[20, 40, 60]" :page-size="form_requst.size"
layout="total, sizes, prev, pager, next, jumper" :total="count" class="m-t-10 m-b-20 table_90"
@size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
</div>
</el-main>
</template>
<script>
import { mapState } from 'vuex'
import { mapActions } from 'vuex'
import { ElMessage, ElLoading } from 'element-plus'
import axios from 'axios'
export default {
data () {
return {
loading: null,
header_style: {
'background-color': '#F5F7FA',
color: '#606266',
fontSize: '10px',
fontWeight: '600',
textAlign: 'center'
},
form_requst: {
page: 1,
size: 20,
model: '',
name: '',
user: '',
edit_time: '',
type: '',
is_new: 1
},
tableData: [],
typeList: [],
count: '',
pickerOptions (time) {
return time.getTime() > Date.now() //选当前时间以后的时间
}
}
},
//清除缓存
beforeRouteUpdate (to, from, next) {
this.form_requst.is_new = to.query.is_new
if (to.fullPath != from.fullPath) {
this.getList(1)
next()
}
},
computed: {
...mapState({
// 取出页面标签
userInfo: state => state.user.userInfo
})
},
activated () {
this.form_requst.is_new = this.$route.query.is_new
this.getList()
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
//日志列表
getList (type) {
if (type == 1) {
this.form_requst.page = 1
}
this.listLoading = true
this.form_requst.is_new = 0
this.$http
.get('cost/getlog', this.form_requst)
.then(res => {
if (res.errno == 200) {
this.tableData = res.data.list
this.count = res.data.count
this.typeList = res.data.type
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
this.listLoading = false
})
},
//分页
handleSizeChange (new_size) {
this.form_requst.size = new_size
this.getList()
},
handleCurrentChange (new_page) {
this.form_requst.page = new_page
this.getList()
},
//批量导出
batchExport () {
console.log(this.userInfo.isall)
this.loading = this.$loading({
lock: true,
text: '此操作需要一段时间请耐心等待...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
/* this.batchExportShow = true*/
const apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
axios
.get(
process.env.VUE_APP_API_BASEURL +
apiVersion +
'/' +
'/cost/exportlog?isall=' +
this.userInfo.isall +
'&is_new=0',
{
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
}
)
.then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const nameStr = decodeURI(escape(JSON.parse(res.headers['content-disposition'].split(';')[1].split('=')[1])))
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
this.loading.close()
})
},
//重置
reset () {
this.form_requst = {
page: 1,
size: 20,
model: '',
name: '',
user: '',
edit_time: '',
type: ''
}
},
//clear select
clear (item) {
if (item == 'type') {
this.form_requst.type = ''
}
this.getList()
},
cancel () {
// let routeData = this.$router.push({
// path: '/mold/index',
// });
// window.opener = null;
// // //新页面中,才能使用如下关闭
// window.close()
this.handleCloseTag()
}
}
}
</script>
<style scoped>
/*新样式*/
.vxe-table--render-default {
font-size: 12px;
}
::v-deep(.vxe-header--column, .vxe-table--render-default) {
padding: 5px 0 !important;
}
::v-deep(.vxe-body--column) {
height: 32px !important;
}
::v-deep(.vxe-table--render-default .vxe-cell) {
padding-left: 2px;
padding-right: 2px;
}
::v-deep(.el-input__inner) {
width: 100% !important;
}
</style>

768
src/views/index/oindex.vue Normal file
View File

@@ -0,0 +1,768 @@
<template>
<el-main class="bg_white">
<div class="m-t-10 table_90 border-r-10 text-black">
<el-row>
<el-col :span="8">
<!-- <el-button type="primary" size="mini" @click="getList(1)">搜索</el-button>
<el-button type="primary" size="mini" @click="reset()">重置</el-button>-->
<el-button type="primary" size="mini" @click="save">保存修改</el-button>
</el-col>
<el-col :span="16" class="text-r">
<!-- <el-button type="primary" size="mini">导入</el-button> -->
<el-button type="primary" size="mini" @click="batchExport">导出</el-button>
<el-button type="primary" size="mini" @click="clickLog">日志</el-button>
<el-button type="primary" size="mini" @click="synchronizeErp">同步ERP数据</el-button>
</el-col>
</el-row>
</div>
<!--表格-->
<div class="bg_white table_90 m-t-10 border-r-10 text-black f-12">
<vxe-table border resizable show-overflow ref="xTable" height="700" :scroll-x="{ enabled: false }"
:scroll-y="{ enabled: false }" :header-row-style="header_style" :data="tableData" :edit-config="editConfig">
<vxe-colgroup title="基本信息" header-align="center" fixed="left" resizable>
<!-- <vxe-colgroup title="品牌" header-align="center">
<vxe-column field="name" width="100">
<template #header>
<el-select v-model="brand_name" placeholder="" @change="selectSKU()" clearable filterable size="mini">
<el-option v-for="(option, index) in brand_list" :key="index"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>-->
<vxe-column field="picture" title="图片" width="80" header-align="center" align="center" class="position-r">
<template #default="{ row }">
<el-upload :action="api_upload_url" :with-credentials="true"
:on-success="function (res, file, file_list) { return handleSuccess(res, file, file_list, row) }"
:show-file-list="false" name="file" accept=".png, .jpg" :on-change="handleChange">
<img v-if="row.picture" :src="row.picture" class="avatar" @mousemove="enlarge($event, row)"
@mouseout="enlargeOut(row)" />
<el-icon v-else class="el-icon-plus">
<plus />
</el-icon>
<view v-show="row.enlargeImgShow" class="img-show position-f" v-if="enlargeImg" :style="top">
<img :src="enlargeImg" />
</view>
</el-upload>
</template>
</vxe-column>
<vxe-colgroup title="规格型号(sku)" header-align="center">
<vxe-column field="model" width="150">
<template #header>
<el-input size="mini" v-model="form_requst.model" @keydown.enter.native="getList(1)"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="产品名称" header-align="center">
<vxe-column field="name" width="120" header-align="center">
<template #header>
<el-input size="mini" v-model="form_requst.name" @keydown.enter.native="getList(1)"></el-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="生命周期" header-align="center">
<vxe-column field="F_PAEZ_Combo2" width="100" header-align="center">
<template #header>
<el-select v-model="form_requst.F_PAEZ_Combo2" placeholder clearable filterable size="mini"
@clear="clear('F_PAEZ_Combo2')">
<el-option v-for="(item, index) in F_PAEZ_Combo2" :key="index" :label="item" :value="item"
@click="getList"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-colgroup title="产品分类" header-align="center">
<vxe-colgroup title="一级分类" header-align="center">
<vxe-column field="category_one" width="100">
<template #header>
<el-select v-model="form_requst.category_one" placeholder clearable filterable size="mini"
@clear="clear('category_one')" ref="select_one">
<el-option v-for="(item1, index) in category_one" :key="index" :label="item1" :value="item1"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="二级分类" header-align="center">
<vxe-column field="category_two" width="100">
<template #header>
<el-select v-model="form_requst.category_two" placeholder clearable filterable size="mini"
@clear="clear('category_two')">
<el-option v-for="(item2, index) in category_two" :key="index" :label="item2" :value="item2"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="三级分类" header-align="center">
<vxe-column field="category_three" width="100">
<template #header>
<el-select v-model="form_requst.category_three" placeholder clearable filterable size="mini"
@clear="clear('category_three')">
<el-option v-for="(item3, index) in category_three" :key="index" :label="item3" :value="item3"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-colgroup header-align="center">
<vxe-colgroup title="项目负责团队" header-align="center">
<vxe-column field="team_user" width="100" header-align="center">
<template #header>
<el-select v-model="form_requst.team_user" placeholder clearable filterable size="mini"
@clear="clear('team_user')">
<el-option v-for="(items, index) in opd_list" :key="index" :label="items" :value="items"
@click="getList(1)"></el-option>
</el-select>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-column field="cost" title="物料成本价" width="80" header-align="center" align="right"
v-allow="'NewCost.NewCostFinance'"></vxe-column>
<vxe-column field="agent_price" title="代理价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.agent_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="retail_price" title="零售指导价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.retail_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="minimum_activity_price" title="最低活动价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.minimum_activity_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="overseas_retail_price" title="海外零售指导价($)" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.overseas_retail_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="overseas_minimum_activity_price" title="海外零售最低活动价($)" width="60" header-align="center"
align="right" :edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.overseas_minimum_activity_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="agent_price" title="代理价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.agent_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="retail_price" title="零售指导价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.retail_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="minimum_activity_price" title="最低活动价" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.minimum_activity_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="overseas_retail_price" title="海外零售指导价($)" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.overseas_retail_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="overseas_minimum_activity_price" title="海外零售最低活动价($)" width="60" header-align="center"
align="right" :edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.overseas_minimum_activity_price" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="factory_price" title="成本价" width="80" header-align="center" align="right"></vxe-column>
<vxe-colgroup title="产品成本构成" header-align="center">
<vxe-column field="clinker_cost" title="结构/本体" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.clinker_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="metal_cost" title="电子" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.metal_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="electron_cost" title="电源" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.electron_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="wire_cost" title="线材" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.wire_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="accessories_cost" title="辅料/配件" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.accessories_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="packing_cost" title="包材" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.packing_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="process_cost" title="加工费" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.process_cost" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="other_cost" title="硬盘/运费其他" width="80" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.other_cost" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-column field="moq" title="MOQ" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.moq" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="packing" title="包装方式" width="80" header-align="center"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.packing" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-colgroup title="产品尺寸重量mm/g" header-align="center">
<vxe-column field="FLENGTH" title="长" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FLENGTH" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FWIDTH" title="宽" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FWIDTH" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FHEIGHT" title="高" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FHEIGHT" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FNETWEIGHT" title="重量" width="120" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FNETWEIGHT" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="包装版本1" header-align="center">
<vxe-colgroup title="包装尺寸重量mm/g" header-align="center">
<vxe-column field="FPACKAGE1" title="包装版本名称" width="60" header-align="center"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FPACKAGE1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FLENGTHP1" title="长" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FLENGTHP1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FWIDTHP1" title="宽" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FWIDTHP1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FHEIGHTP1" title="高" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FHEIGHTP1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FNETWEIGHTP1" title="重量" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FNETWEIGHTP1" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
<vxe-colgroup title="装箱信息(mm/Kg)" header-align="center">
<vxe-column field="FQtyC1" title="数量" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FQtyC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FLENGTHC1" title="长" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FLENGTHC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FWIDTHC1" title="宽" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FWIDTHC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FHEIGHTC1" title="高" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FHEIGHTC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FNETWEIGHTC1" title="净重" width="60" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FNETWEIGHTC1" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="FGROSSWEIGHTC1" title="毛重" width="120" header-align="center" align="right"
:edit-render="{ autofocus: '.vxe-input--inner' }">
<template #edit="{ row }">
<vxe-input v-model="row.FGROSSWEIGHTC1" type="text"></vxe-input>
</template>
</vxe-column>
</vxe-colgroup>
</vxe-colgroup>
<vxe-column field="edit_time" title="上次更新" width="120" header-align="center" align="right"></vxe-column>
</vxe-table>
<el-pagination :current-page="form_requst.page" :page-sizes="[10, 20, 30]" :page-size="form_requst.size"
layout="total, sizes, prev, pager, next, jumper" :total="count" class="m-t-10 m-b-20 table_90"
@size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
</div>
<!--价格修改-->
</el-main>
</template>
<script>
import { mapState } from 'vuex'
import { ElMessage, ElLoading } from 'element-plus'
import axios from 'axios'
export default {
data () {
return {
header_style: {
'background-color': '#F5F7FA',
color: '#606266',
fontSize: '10px',
fontWeight: '600',
textAlign: 'center'
},
brand_list: [],
sku_list: [],
name_list: [],
F_PAEZ_Combo2: [],
one_cate_list: [],
two_cate_list: [],
three_cate_list: [],
is_211: [],
supplier_list: [],
form_requst: {
page: 1,
size: 20,
model: '',
name: '',
F_PAEZ_Combo2: '',
category_one: '',
category_two: '',
category_three: '',
team_user: '',
is_new: 0
},
model: '',
name: '',
F_PAEZ_Combo2: '',
category_one: '',
category_two: '',
category_three: '',
opd_list: '',
form_buy: '',
fast: '',
supplier: '',
count: 0,
tableData: null,
save_form: [],
add_form: {
id: '',
key: '',
value: ''
},
CostFinance: '',
listLoading: '',
old_value: '',
enlargeImgShow: false,
enlargeImg: '',
top: ''
}
},
computed: {
...mapState({
// 取出页面标签
userInfo: state => state.user.userInfo
}),
editConfig () {
if (this.userInfo.isall == 1) {
return { trigger: 'click', mode: 'cell' }
}
},
api_upload_url () {
return process.env.VUE_APP_API_BASEURL + 'admin/Upload/uploadImgDemo'
}
},
created () {
this.getList()
},
methods: {
enlarge (e, row) {
console.log(e)
this.enlargeImg = row.picture
row.enlargeImgShow = true
this.top = 'top:' + e.clientY + 'px'
},
enlargeOut (row) {
row.enlargeImgShow = false
this.enlargeImg = ''
},
//成本列表
getList (type) {
if (type == 1) {
this.form_requst.page = 1
}
this.listLoading = true
this.$http
.get('cost/list', this.form_requst)
.then(res => {
if (res.errno == 200) {
res.data.list.forEach((item, index) => {
item.enlargeImgShow = false
})
this.tableData = res.data.list
this.brand = res.data.brand
this.F_PAEZ_Combo2 = res.data.F_PAEZ_Combo2
this.category_one = res.data.category_one
this.category_two = res.data.category_two
this.category_three = res.data.category_three
this.supplier = res.data.supplier
this.count = res.data.count
this.form_buy = res.data.form_buy
this.fast = res.data.fast
this.opd_list = res.data.opd
this.tableData.forEach(item => {
item.is_show = 1
})
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
this.listLoading = false
})
},
//clear select
clear (item) {
if (item == 'F_PAEZ_Combo2') {
this.form_requst.F_PAEZ_Combo2 = ''
}
if (item == 'category_one') {
this.form_requst.category_one = ''
}
if (item == 'category_two') {
this.form_requst.category_two = ''
}
if (item == 'category_three') {
this.form_requst.category_three = ''
}
if (item == 'team_user') {
this.form_requst.team_user = ''
}
this.getList()
},
//重置
reset () {
this.form_requst = {
page: 1,
size: 20,
model: '',
name: '',
F_PAEZ_Combo2: '',
category_one: '',
category_two: '',
category_three: '',
team_user: ''
}
this.getList()
},
//分页
handleSizeChange (new_size) {
this.form_requst.size = new_size
this.getList()
},
handleCurrentChange (new_page) {
this.form_requst.page = new_page
this.getList()
},
tableRowClassName ({ row, rowIndex }) {
if (rowIndex == this.rowClassName) {
return this.classNameRow
}
return ''
},
//编辑
handleClick (index, row) {
this.rowClassName = index
this.classNameRow = 'current-row'
row.is_show = 0
this.buttonEdit = false
this.buttonSave = true
},
//保存修改
save () {
console.log(this.tableData, 'this.tableData')
this.$http
.post('cost/edit', this.tableData)
.then(res => {
if (res.errno == 200) {
ElMessage({
type: 'success',
message: res.errmsg
})
this.getList()
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
// listLoading.close()
})
},
//同步ERP
synchronizeErp () {
const listLoading = ElLoading.service({
lock: true,
text: '同步ERP可能需要几分钟请耐心等待...'
})
this.$http
.get('cost/geterpinfo?is_new=0')
.then(res => {
if (res.errno == 200) {
ElMessage({
type: 'success',
message: res.errmsg
})
this.getList()
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
.finally(() => {
listLoading.close()
})
},
//批量导出
batchExport () {
// this.batchExportShow = true
const listLoading = this.$loading({
lock: true,
text: '此操作需要一段时间请耐心等待...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
const apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
axios
.get(process.env.VUE_APP_API_BASEURL + apiVersion + '/' + '/cost/export?is_new=0&isall=' + this.userInfo.isall, {
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
})
.then(res => {
listLoading.close()
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const nameStr = decodeURI(escape(JSON.parse(res.headers['content-disposition'].split(';')[1].split('=')[1])))
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
},
//日志
clickLog () {
this.$router.push({
path: '/index/log',
query: { is_new: 0 }
})
},
//上传图片
handleSuccess (res, file, file_list, item) {
console.log(item, 'item')
if (res.status == 200) {
// ElMessage({
// type: 'success',
// message: res.message,
// })
item.picture = res.data.imgpath
const formQuery = {
id: item.id,
picture: item.picture
}
this.$http.post('cost/saveImg', formQuery).then(ress => {
if (ress.errno == 200) {
ElMessage({
type: 'success',
message: ress.errmsg
})
} else {
ElMessage({
type: 'error',
message: ress.errmsg
})
}
})
} else {
file_list.splice(file_list.length - 1, 1)
ElMessage({
type: 'error',
message: res.errmsg
})
}
},
//上传前色子
//上传文件限制
handleChange (file, fileList) {
const isLt5M = file.size / 1024 / 1024 < 1
if (!isLt5M) {
ElMessage({
type: 'error',
message: '上传文件大小不能超过 1MB'
})
file = null
fileList = []
this.$refs.upload.clearFiles() // 清除前端显示的文件列表
} else {
if (file.status === 'ready') {
this.uploadFile = file.raw
}
}
}
}
}
</script>
<style scoped>
/*新样式*/
.vxe-table--render-default {
font-size: 12px;
}
::v-deep(.vxe-header--column, .vxe-table--render-default) {
padding: 5px 0 !important;
}
::v-deep(.vxe-body--column) {
height: 32px !important;
}
::v-deep(.vxe-table--render-default .vxe-cell) {
padding-left: 2px;
padding-right: 2px;
}
.select-class {
z-index: 10 !important;
position: absolute;
left: 0;
top: 50%;
margin-top: -14px;
}
::v-deep(.el-upload-list--picture-card .el-upload-list__item) {
margin-bottom: 0px !important;
width: 40px !important;
height: 40px !important;
}
::v-deep(.el-upload-list__item),
::v-deep(.vxe-body--row) {
width: 40px !important;
height: 50px !important;
line-height: 40px !important;
}
::v-deep(.el-upload-list__item) {
position: absolute;
}
::v-deep(.avatar) {
width: 40px;
height: 40px;
padding-top: 5px;
padding-bottom: 5px;
}
::v-deep(.el-icon-plus) {
width: 40px;
height: 40px;
border-radius: 2px;
line-height: 40px;
border: 1px dashed rgba(0, 0, 0, 0.1);
}
.img-show {
width: 150px;
height: 150px;
border: 1px solid rgba(0, 0, 0, 0.1);
overflow: hidden;
z-index: 9;
background-color: #fff;
vertical-align: middle;
margin-top: -60px;
text-align: center;
}
.img-show img {
z-index: 10;
max-width: 150px;
vertical-align: middle;
}
</style>

50
src/views/login/index.vue Normal file
View File

@@ -0,0 +1,50 @@
<template>
<el-main></el-main>
</template>
<script>
import { setSignedIn } from '@/utils/auth'
import { mapActions } from 'vuex'
import { ElLoading } from 'element-plus'
export default {
name: 'Login',
data() {
return {}
},
created() {
ElLoading.service({ lock: true })
const code = this.$route.query.code
if (typeof code === 'undefined') {
const redirectURL = encodeURIComponent(window.location.href)
setTimeout(() => (location.href = buildRedirectURL(redirectURL)), 1000)
} else {
this.$http
.showLoading(false)
.mock(false)
.post('login/login', { code: code })
.then(r => {
if (r.errno === 0 && r.data.signed_in) {
setSignedIn() // 设为已登录
this.setUserInfo(r.data.user_info)
setTimeout(() => this.$router.push({ path: '/index/index' }), 1000)
} else {
console.log('aa')
this.$message.error(r.errmsg)
const redirectURL = encodeURIComponent(window.location.protocol + '//' + window.location.host + window.location.pathname)
setTimeout(() => (location.href = buildRedirectURL(redirectURL)), 1500)
}
})
}
},
methods: {
...mapActions({
setUserInfo: 'user/setUserInfo'
})
}
}
// 组装重定向链接
const buildRedirectURL = redirectURL => {
const loginURL = process.env.VUE_APP_SSO_LOGINURL
const APPID = process.env.VUE_APP_SSO_APPID
return loginURL + '?app_id=' + APPID + '&redirect_url=' + redirectURL + '&response_type=code'
}
</script>

859
src/views/mold/add_mold.vue Normal file
View File

@@ -0,0 +1,859 @@
<template>
<div class="mold-header table_90 f-12">
<el-row>
<!--表单-->
<el-form :inline="true" :model="formInline" :rules="rules" class="demo-form-inline">
<el-row :gutter="10">
<el-col :span="12" v-if="formInline.dotype != 'add'">
<el-form-item label="模具编号" label-width="78px" prop="number">{{ formInline.matrix_sn }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="模具名称" prop="matrix_title">
<el-input
v-model="formInline.matrix_title"
placeholder="模具名称"
maxlength="255"
style="width: 480px"
></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-row>
<!--表格-->
<div class="table_90 f-12">
<h2>
模具关联半成品管理
<span style="font-size: 0.5em; font-weight: 500">此处只关联直接由模具生产的物料信息</span>
</h2>
<vxe-table
border
:data="tableColumn"
style="margin-top: 15px"
ref="xTable"
:edit-config="{ trigger: 'click', mode: 'row' }"
row-id="keyid"
:edit-rules="rules"
>
<vxe-column field="produce_sn" title="半成品物料编码" :edit-render="{}" prop="produce_sn">
<template #edit="{ row }">
<vxe-input
v-model="row.produce_sn"
@blur="getMaterial(row.produce_sn, row.keyid)"
type="text"
></vxe-input>
</template>
</vxe-column>
<vxe-column field="id" title="id" :visible="false"></vxe-column>
<vxe-column field="produce_titile" title="半成品物料名称"></vxe-column>
<vxe-column field="produce_sku" title="半成品物料规格型号sku"></vxe-column>
<vxe-column field="holes_num" title="模具穴数" :edit-render="{}" prop="holes_num">
<template #edit="{ row }">
<vxe-input
v-model.number="row.holes_num"
@blur="getHolesNum(row.holes_num, row.keyid, 1)"
type="text"
maxlength="7"
></vxe-input>
</template>
</vxe-column>
<vxe-column field="capacity_num" title="模具产能(每小时)" :edit-render="{}">
<template #edit="{ row }">
<vxe-input
v-model="row.capacity_num"
@blur="getHolesNum(row.capacity_num, row.keyid, 2)"
type="text"
maxlength="7"
></vxe-input>
</template>
</vxe-column>
<vxe-column field="operation" title="操作" width="100">
<template #default="{ row }">
<el-button size="mini" @click="removeRow(row)" status="danger">删除行</el-button>
</template>
</vxe-column>
</vxe-table>
<vxe-button @click="insertEvent(-1)" class="mold-header" status="primary">新增行</vxe-button>
</div>
<!--表格-->
<div class="table_90 f-12">
<h2 style="display: contents">
关联成品型号
<span style="font-size: 0.5em; font-weight: 500">此处只关联上方半成品可生产的成品信息</span>
</h2>
<el-button type="text" style="margin-left: 200px" size="small" @click="getProductList">获取成品信息</el-button>
<vxe-table border :data="productList">
<vxe-column field="product_sn" title="成品物料编码"></vxe-column>
<vxe-column field="id" title="id" :visible="false"></vxe-column>
<vxe-column field="product_name" title="成品物料名称"></vxe-column>
<vxe-column field="product_sku" title="成品物料规格型号sku"></vxe-column>
</vxe-table>
</div>
<div class="mold-header table_90 f-12">
<el-row>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-row>
<el-col :span="6">
<el-form-item label="模具类型" label-width="85px" required>
<el-select v-model="formInline.type" filterable placeholder="请选择">
<el-option
v-for="(item, key, index) of matrix_type"
:key="key"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="有无复制模" label-width="85px" required>
<el-select v-model="formInline.is_copy_matrix" filterable placeholder="请选择">
<el-option
v-for="(item, key, index) of is_copy_matrixs"
:key="key"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具费用" label-width="115px">
<el-input
v-model="formInline.cost_price"
placeholder="模具费用"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)"
onafterpaste="this.value=this.value.match(/\d+\.?\d{0,2}/)"
maxlength="7"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具费用返还标准(万次)">
<el-input
v-model="formInline.return_standard"
placeholder="模具费用返还标准(万次)"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)"
onafterpaste="this.value=this.value.match(/\d+\.?\d{0,2}/)"
maxlength="7"
></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请开模时间">
<el-date-picker
v-model="formInline.matrix_start"
type="date"
placeholder="请选择申请开模时间"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模完成时间">
<el-date-picker
v-model="formInline.matrix_finish"
type="date"
placeholder="请选择开模完成时间"
style="110%"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具设计寿命(万次)">
<el-input
v-model="formInline.matrix_life"
placeholder="模具设计寿命(万次)"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)"
onafterpaste="this.value=this.value.match(/\d+\.?\d{0,2}/)"
maxlength="7"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具状态" label-width="140px">
<el-select
v-model="formInline.status"
filterable
placeholder="请选择"
style="width: 92%"
>
<el-option
v-for="(item, key, index) of matrix_status"
:key="key"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模申请组织" label-width="95px" required>
<el-select
v-model="formInline.org_id"
@change="changeOrg"
filterable
placeholder="请选择"
>
<el-option
v-for="(item, index) in uc_orgs"
:label="item.org_name"
:value="item.org_id"
:key="index + '111'"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模申请部门" label-width="95px" required>
<el-cascader
@change="changeDept"
:options="depts"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
checkStrictly: true
}"
></el-cascader>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模申请人" label-width="115px" required>
<!-- <el-input v-model="formInline.applicant" placeholder="开模申请人" style="width:110%;"></el-input> -->
<el-select v-model="formInline.matrix_apply" filterable placeholder="请选择">
<el-option
v-for="(item, index) in uc_staffs"
:label="item.staff_name"
:value="item.staff_name"
:key="index + '111'"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具供应商" label-width="140px">
<!-- <el-input v-model="formInline.supplier" placeholder="模具供应商" style="width:110%;"></el-input> -->
<el-select v-model="formInline.supplier" filterable placeholder="请选择">
<el-option
v-for="(item, index) in uc_suppliers"
:label="item.sup_name"
:value="item.sup_name"
:key="index + '222'"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物料生产供应商(模具所在地)" label-width="85px" aligh="right">
<el-select v-model="formInline.produc_supplier" filterable placeholder="请选择">
<el-option
v-for="(item, index) in uc_suppliers"
:label="item.sup_name"
:value="item.sup_name"
:key="index + '333'"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="模具管理协议" label-width="100px">
<el-upload
class="upload-demo"
:action="api_upload_url"
:on-change="handleChange"
:on-preview="getDownload"
:on-success="handleAvatarSuccess"
:on-exceed="cickCtips"
name="file"
:file-list="fileList"
:with-credentials="true"
:limit="1"
:before-upload="onBeforeUpload"
:multiple="false"
accept=".jpg, .png, .pdf"
>
<el-button size="small" type="primary">
<i class="el-icon-plus"></i>上传协议
</el-button>
<template #tip>
<div class="el-upload__tip">上传文件支持jpg/png/pdf 最大限制上传 10M</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" label-width="100px">
<vxe-textarea
v-model="formInline.remark"
placeholder="显示字数统计"
rows="4"
maxlength="255"
show-word-count
style="width: 1500px"
></vxe-textarea>
</el-form-item>
</el-col>
<div class="click-btn">
<el-button type="primary" size="small" @click="onSubmit" class="btn-save">保存</el-button>
<!-- <el-button plain size="small" @click="cancel" class="btn-cancel">取消</el-button> -->
</div>
</el-row>
</el-form>
</el-row>
</div>
</div>
</template>
<script>
import { Plus, ZoomIn, Download, Delete } from '@element-plus/icons'
import { ElMessage } from 'element-plus'
import { mapActions, mapState } from 'vuex'
import download from 'downloadjs' //下载依赖
export default {
components: {
Plus,
ZoomIn,
Download,
Delete,
},
data() {
return {
depts: [], //申请部门
fileList: [],
// imageUrl: '', // 图片路径
tableData: [],
tableColumn: [],
productList: [], //成品
pro_num: [],
formInline: {
matrix_title: '',
matrix_data: [],
product_data: [], //提交的成品信息
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'add',
id: 0,
org_id: '',
dept_code: '',
},
//验证规则
rules: {
matrix_title: [
{ required: true, message: '请填写模具名称', trigger: 'blur' },
],
matrix_apply: [
{ required: true, message: '请选择开模申请人', trigger: 'blur' },
],
},
value1: '',
value2: '',
is_copy_matrixs: {},
matrix_type: {},
matrix_status: {},
uc_staffs: [],
uc_suppliers: [],
uc_orgs: [],
is_submit: true,
matrix_id: '',
}
},
created() {
this.matrix_id = this.$route.query.matrix_id
this.getSupplierData()
this.findList()
this.getMaterialList()
},
//清除缓存
activated() {
this.matrix_id = this.$route.query.matrix_id
if (this.$route.query.type == 0) {
;(this.fileList = []),
(this.tableColumn = []),
(this.formInline = {
matrix_title: '',
matrix_data: [],
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'add',
id: 0,
})
}
},
//清除缓存
beforeRouteUpdate(to, from, next) {
this.matrix_id = to.query.matrix_id
if (to.fullPath != from.fullPath) {
this.getSupplierData()
next()
}
},
computed: {
api_upload_url() {
var apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
return (
process.env.VUE_APP_API_BASEURL + apiVersion + '/upload/uploadImgDemo'
)
},
...mapState({
// 取出页面标签
tags: (state) => state.topNavTag.tags,
}),
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag',
}),
getHolesNum(nusds, keyid, typee) {
if (!/^[1-9]\d*$/.test(nusds)) {
ElMessage({
type: 'error',
message: '请输入正整数',
})
this.tableColumn.forEach((item, index) => {
if (keyid == item.keyid) {
if (typee == 1) {
item.holes_num = 0
}
if (typee == 2) {
item.capacity_num = 0
}
}
})
}
},
getMatrixInfo(matrix_id) {
this.formInline = {
matrix_title: '',
matrix_data: [],
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'add',
id: 0,
org_id: 0,
dept_code: 0,
}
this.tableColumn = []
this.$http
.post('matrix/getMatrixInfo', { id: matrix_id })
.then((ress) => {
if (ress.status == 200) {
if (ress.data != '') {
this.formInline = ress.data
this.formInline.dotype = 'edit'
this.tableColumn = ress.data.matrix_data_arr
this.productList = ress.data.product_data
console.log(this.productList)
this.fileList = []
if (ress.data.agreement != '') {
var agreement = {
name: ress.data.agreement,
url: ress.data.agreement,
}
this.fileList.push(agreement)
}
}
//获取部门组织
this.getSupplierData()
this.getDepts()
}
})
},
getMaterialList() {
this.$http.post('matrix/getMaterial').then((ret) => {
if (ret.status == 200) {
this.pro_num = ret.data.results
}
})
},
//输入匹配
getMaterial(produce_sn, keyid) {
this.$http
.post('matrix/getMaterial', { fnumber: produce_sn })
.then((ret) => {
if (ret.status == 200) {
if (ret.data.results == '' || ret.data.results == null) {
ElMessage({
type: 'error',
message: '该生产物料编码不存在!',
})
return false
}
this.tableColumn.forEach((item, index) => {
if (keyid == item.keyid) {
if (ret.data.results.FNAME == '') {
item.produce_titile = ''
item.produce_sku = ''
item.produce_id = ''
} else {
item.produce_titile = ret.data.results.FNAME
item.produce_sku = ret.data.results.FSPECIFICATION
item.produce_id = ret.data.results.FMATERIALID
}
}
})
} else {
ElMessage({
type: 'error',
message: '请求错误',
})
}
})
},
getSupplierData() {
this.$http.post('matrix/getSupplier', {}).then((ret) => {
this.is_copy_matrixs = ret.data.is_copy_matrixs
this.matrix_type = ret.data.matrix_type
this.matrix_status = ret.data.matrix_status
// this.uc_staffs = ret.data.uc_staffs
this.uc_suppliers = ret.data.uc_suppliers
this.uc_orgs = ret.data.uc_orgs
// this.depts = ret.data.uc_depts
if (this.matrix_id != '' || this.matrix_id != undifend) {
this.getMatrixInfo(this.matrix_id)
}
})
},
//获取部门
getDepts() {
this.$http
.get('matrix/getDepts', { org_id: this.formInline.org_id })
.then((ret) => {
this.depts = ret.data.uc_depts
})
},
//获取员工
getStaff() {
this.$http
.get('matrix/getStaffs', { org_id: this.formInline.org_id })
.then((ret) => {
this.uc_staffs = ret.data.uc_staffs
})
},
//开模申请组织修改后
changeOrg() {
this.formInline.dept_code = '' //重置开模申请部门
this.formInline.matrix_apply = '' //重置开模申请人
//重新获取信息
this.getDepts()
this.getStaff()
},
changeDept(val) {
console.log(val)
this.formInline.dept_code = val[val.length - 1]
},
//删除行
async removeRow(row) {
console.log('row --->', row)
// this.tableColumn.
const $table = this.$refs.xTable
await $table.remove(row)
this.tableColumn.forEach((item, index) => {
if (item.keyid == row.keyid) {
this.tableColumn.splice(index, 1)
}
})
},
// 增加行
async insertEvent(row) {
const $table = this.$refs.xTable
const record = {
id: '',
produce_sn: '',
produce_titile: '',
produce_sku: '',
holes_num: 0,
capacity_num: 0,
}
const { row: newRow } = await $table.insertAt(record, row)
await $table.setActiveCell(newRow, 'name')
this.tableColumn.push(newRow)
},
//表格
findList() {
this.loading = true
var that = this
setTimeout(() => {
var list = [
{
id: '',
produce_sn: '',
produce_titile: '',
produce_sku: '',
holes_num: 0,
capacity_num: 0,
},
]
that.tableColumn = list
this.loading = false
}, 100)
},
authRes() {
this.tableColumn.forEach((item, index) => {
if (item.produce_sku == undefined) {
ElMessage({ type: 'error', message: '可生产物料编码不存在' })
return false
}
})
setTimeout(() => {
this.is_submit = true
}, 500)
},
//保存提交
onSubmit() {
this.authRes()
if (this.is_submit == true) {
//获取成品信息 再提交
this.$http
.post('matrix/getProduct', { list: this.tableColumn })
.then((ret) => {
if (ret.status == 200) {
this.productList = ret.data.results
}
//提交
this.formInline.matrix_data = JSON.stringify(this.tableColumn)
this.formInline.product_data = JSON.stringify(this.productList)
this.$http
.post('matrix/saveMatrix', this.formInline)
.then((ret) => {
if (ret.status == 200) {
ElMessage({
type: 'success',
message: ret.message,
})
this.$router.push({
path: '/mold/index',
})
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(
(it) => it.name === currentPageName
)
if (idx >= 0) {
this.handleCloseTag(idx)
}
} else {
ElMessage({
type: 'error',
message: ret.message,
})
}
})
})
}
},
//关闭子页面
cancel() {
// let routeData = this.$router.push({
// path: '/mold/index',
// });
// window.opener = null;
// // //新页面中,才能使用如下关闭
// window.close()
this.handleCloseTag()
},
getProductList() {
//半成品物料为空判断
if (this.tableColumn.length <= 0) {
ElMessage({
type: 'error',
message: '请填写半成品物料',
})
return false
}
this.$http
.post('matrix/getProduct', { list: this.tableColumn })
.then((ret) => {
if (ret.status == 200) {
this.productList = ret.data.results
} else {
ElMessage({
type: 'error',
message: ret.message,
})
}
})
},
//上传文件校验
onBeforeUpload(file) {
const isIMAGE =
file.type === 'image/jpg' ||
file.type === 'image/jpeg' ||
file.type === 'application/pdf' ||
file.type === 'image/png'
const isLt10M = file.size / 1024 / 1024 < 10
if (!isIMAGE) {
ElMessage({
type: 'error',
message: '上传文件格式错误!',
})
this.fileList = []
}
if (!isLt10M) {
ElMessage({
type: 'error',
message: '超出文件上传大小!',
})
this.fileList = []
}
return isIMAGE && isLt10M
},
//远程输入框搜索
querySearchAsync(queryString, cb) {
var restaurants = this.restaurants
var results = queryString
? restaurants.filter(this.createStateFilter(queryString))
: restaurants
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
cb(results)
}, 3000 * Math.random())
},
createStateFilter(queryString) {
return (state) => {
return (
state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
)
}
},
handleSelect(item) {
console.log(item)
},
//下载
getDownload() {
download(this.formInline.agreement)
},
//正负数,含小数
isFloor() {
var obj = event.target
var t = obj.value.charAt(0)
obj.value = obj.value
.replace('.', '$#$') //把第一个字符'.'替换成'$#$'
.replace(/\./g, '') //把其余的字符'.'替换为空
.replace('$#$', '.') //把字符'$#$'替换回原来的'.'
.replace(/[^\d.]/g, '') //只能输入数字和'.'
.replace(/^\./g, '') //不能以'.'开头
.replace(/([0-9]+\.[0-9]{2})[0-9]*/, '$1') //只保留2位小数
if (t == '-') {
obj.value = '-' + obj.value
}
},
// 管理上传
handleAvatarSuccess(res, file) {
this.formInline.agreement = res.data.imgpath
},
handleChange(file, fileList) {
this.fileList = fileList.slice(-3)
},
cickCtips(files, fileList) {
ElMessage({
type: 'error',
message: '文件已上传,如要替换请先删除!',
})
},
},
}
</script>
<style scoped>
::v-deep(.vxe-table--render-default
.vxe-body--column:not(.col--ellipsis), .vxe-table--render-default
.vxe-footer--column:not(.col--ellipsis), .vxe-table--render-default
.vxe-header--column:not(.col--ellipsis)) {
padding: 5px 0;
font-size: 12px;
}
::v-deep(.el-form-item__label) {
line-height: 22px;
padding: 8px 12px 12px 0;
font-size: 12px;
}
::v-deep(.vxe-table--main-wrapper) {
font-size: 12px;
}
.mold-header {
margin: 20px;
}
.m-t-20 {
margin: 20px 0;
}
::v-deep(.el-form-item) {
margin-bottom: 20px;
}
.u-t-r {
text-align: right;
}
.click-btn {
width: 100%;
margin: auto;
text-align: center;
}
.btn-save {
width: 150px;
line-height: 28px;
margin-right: 20px;
margin-right: 20px;
}
.btn-cancel {
width: 150px;
line-height: 28px;
}
</style>

View File

@@ -0,0 +1,701 @@
<template>
<div class="mold-header table_90 f-12">
<el-row>
<!--表单-->
<el-form :inline="true" :model="formInline" :rules="rules" class="demo-form-inline">
<el-row :gutter="10">
<el-col :span="12" v-if="formInline.dotype != 'add'">
<el-form-item label="模具编号" label-width="78px" prop="number">
{{ formInline.matrix_sn }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="模具名称" prop="matrix_title">
<el-input v-model="formInline.matrix_title" placeholder="模具名称" maxlength="255" style="width: 480px"> </el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-row>
<!--表格-->
<div class="table_90 f-12">
<h2>模具关联半成品管理<span style="font-size: 0.5em; font-weight: 500">此处只关联直接由模具生产的物料信息</span></h2>
<vxe-table border :data="tableColumn" ref="xTable" :edit-config="{ trigger: 'click', mode: 'row' }" row-id="keyid" :edit-rules="rules">
<vxe-column field="produce_sn" title="半成品物料编码" :edit-render="{}" prop="produce_sn">
<template #edit="{ row }">
<vxe-input v-model="row.produce_sn" @blur="getMaterial(row.produce_sn, row.keyid)" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="id" title="id" :visible="false"> </vxe-column>
<vxe-column field="produce_titile" title="半成品物料名称"></vxe-column>
<vxe-column field="produce_sku" title="半成品物料规格型号sku"> </vxe-column>
<vxe-column field="holes_num" title="模具穴数" :edit-render="{}" prop="holes_num">
<template #edit="{ row }">
<vxe-input v-model.number="row.holes_num" @blur="getHolesNum(row.holes_num, row.keyid, 1)" type="text" maxlength="7"> </vxe-input>
</template>
</vxe-column>
<vxe-column field="capacity_num" title="模具产能(每小时)" :edit-render="{}">
<template #edit="{ row }">
<vxe-input v-model="row.capacity_num" @blur="getHolesNum(row.capacity_num, row.keyid, 2)" type="text" maxlength="7"> </vxe-input>
</template>
</vxe-column>
<vxe-column field="operation" title="操作" width="100">
<template #default="{ row }">
<el-button size="mini" @click="removeRow(row)" status="danger">删除行</el-button>
</template>
</vxe-column>
</vxe-table>
<vxe-button @click="insertEvent(-1)" class="mold-header" status="primary">新增行</vxe-button>
</div>
<!--表格-->
<div class="table_90 f-12">
<h2 style="display: contents">关联成品型号<span style="font-size: 0.5em; font-weight: 500">此处只关联上方半成品可生产的成品信息</span></h2>
<el-button type="text" style="margin-left: 200px" size="small" @click="getProductList">获取成品信息</el-button>
<vxe-table border :data="productList">
<vxe-column field="product_sn" title="成品物料编码"> </vxe-column>
<vxe-column field="id" title="id" :visible="false"> </vxe-column>
<vxe-column field="product_name" title="成品物料名称"></vxe-column>
<vxe-column field="product_sku" title="成品物料规格型号sku"> </vxe-column>
</vxe-table>
</div>
<div class="mold-header table_90 f-12">
<el-row>
<!--表单-->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-row>
<el-col :span="6">
<el-form-item label="模具类型" label-width="85px" required>
<el-select v-model="formInline.type" filterable placeholder="请选择">
<el-option v-for="(item, key, index) of matrix_type" :key="key" :label="item" :value="index"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="有无复制模" label-width="85px" required>
<el-select v-model="formInline.is_copy_matrix" filterable placeholder="请选择">
<el-option v-for="(item, key, index) of is_copy_matrixs" :key="key" :label="item" :value="index"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具费用" label-width="115px">
<el-input v-model="formInline.cost_price" placeholder="模具费用" onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)" onafterpaste="this.value=this.value.match(/\d+\.?\d{0,2}/)" maxlength="7" style="width: 220px"> </el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具费用返还标准(万次)">
<el-input v-model="formInline.return_standard" placeholder="模具费用返还标准(万次)" onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)" onafterpaste="this.value=this.value.match(/\d+\.?\d{0,2}/)" maxlength="7"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请开模时间">
<el-date-picker v-model="formInline.matrix_start" type="date" placeholder="请选择申请开模时间"> </el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模完成时间">
<el-date-picker v-model="formInline.matrix_finish" type="date" placeholder="请选择开模完成时间" style="110%"> </el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具设计寿命(万次)">
<el-input v-model="formInline.matrix_life" placeholder="模具设计寿命(万次)" onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)" onafterpaste="this.value=this.value.match(/\d+\.?\d{0,2}/)" maxlength="7" style="width: 220px"> </el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具状态" label-width="140px">
<el-select v-model="formInline.status" filterable placeholder="请选择" style="width: 92%">
<el-option v-for="(item, key, index) of matrix_status" :key="key" :label="item" :value="index"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模申请组织" label-width="95px" required>
<el-select v-model="formInline.org_id" @change="changeOrg" filterable placeholder="请选择">
<el-option v-for="(item, index) in uc_orgs" :label="item.org_name" :value="item.org_id" :key="index + '111'"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模申请部门" label-width="95px" required>
<el-cascader
v-model="formInline.dept_code"
@change="changeDept"
:options="depts"
:props="{
expandTrigger: 'hover',
value: 'dept_code',
label: 'dept_name',
children: 'children',
checkStrictly: true
}"
></el-cascader>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开模申请人" label-width="115px" required>
<!-- <el-input v-model="formInline.applicant" placeholder="开模申请人" style="width:110%;"></el-input> -->
<el-select v-model="formInline.matrix_apply" filterable placeholder="请选择">
<el-option v-for="(item, index) in uc_staffs" :label="item.staff_name" :value="item.staff_name" :key="index + '111'"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="模具供应商" label-width="85px">
<el-select v-model="formInline.supplier" filterable placeholder="请选择">
<el-option v-for="(item, index) in uc_suppliers" :label="item.sup_name" :value="item.sup_name" :key="index + '222'"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物料生产供应商(模具所在地)" label-width="118px" aligh="right">
<el-select v-model="formInline.produc_supplier" filterable placeholder="请选择">
<el-option v-for="(item, index) in uc_suppliers" :label="item.sup_name" :value="item.sup_name" :key="index + '333'"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="模具管理协议" label-width="100px">
<el-upload class="upload-demo" :action="api_upload_url" :before-upload="onBeforeUpload" :on-change="handleChange" :on-success="handleAvatarSuccess" :on-exceed="cickCtips" :on-preview="getDownload" name="file" :file-list="fileList" :with-credentials="true" :limit="1" :multiple="false" accept=".jpg,.png,.pdf">
<el-button size="small" type="primary"><i class="el-icon-plus"></i>上传协议</el-button>
<template #tip>
<div class="el-upload__tip">上传文件支持jpg/png/pdf 最大限制上传 10M</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" label-width="100px">
<vxe-textarea v-model="formInline.remark" placeholder="显示字数统计" rows="4" maxlength="255" show-word-count style="width: 1500px"> </vxe-textarea>
</el-form-item>
</el-col>
<div class="click-btn">
<el-button type="primary" size="small" @click="onSubmit" class="btn-save">保存</el-button>
<!-- <el-button plain size="small" @click="cancel" class="btn-cancel">取消</el-button> -->
</div>
</el-row>
</el-form>
</el-row>
</div>
</div>
</template>
<script>
import { Plus, ZoomIn, Download, Delete } from '@element-plus/icons'
import download from 'downloadjs' //下载依赖
import { mapActions, mapState } from 'vuex'
import { ElMessage } from 'element-plus'
export default {
components: {
Plus,
ZoomIn,
Download,
Delete
},
data() {
return {
depts: [], //申请部门
fileList: [],
// imageUrl: '', // 图片路径
tableData: [],
tableColumn: [],
productList: [], //成品
pro_num: [],
uc_orgs: [],
formInline: {
matrix_title: '',
matrix_data: [],
product_data: [], //提交的成品信息
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'edit',
id: 0,
org_id: '',
dept_code: ''
},
//验证规则
rules: {
matrix_title: [{ required: true, message: '请填写模具名称', trigger: 'blur' }],
matrix_apply: [{ required: true, message: '请选择开模申请人', trigger: 'blur' }]
},
value1: '',
value2: '',
is_copy_matrixs: {},
matrix_type: {},
matrix_status: {},
uc_staffs: [],
uc_suppliers: [],
is_submit: true,
matrix_id: ''
}
},
created() {
this.matrix_id = this.$route.query.matrix_id
this.findList()
this.getMaterialList()
},
activated() {
this.matrix_id = this.$route.query.matrix_id
if (this.$route.query.type == 0) {
;(this.fileList = []),
(this.tableColumn = []),
(this.formInline = {
matrix_title: '',
matrix_data: [],
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'edit',
id: 0,
org_id: 0,
dept_code: 0
})
}
this.getMatrixInfo(this.matrix_id)
},
//清除缓存
beforeRouteUpdate(to, from, next) {
this.matrix_id = to.query.matrix_id
if (to.fullPath != from.fullPath) {
this.getMatrixInfo(this.matrix_id)
next()
}
},
computed: {
api_upload_url() {
var apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
return process.env.VUE_APP_API_BASEURL + apiVersion + '/upload/uploadImgDemo'
},
...mapState({
// 取出页面标签
tags: state => state.topNavTag.tags
})
},
methods: {
...mapActions({
// 关闭标签及页面
handleCloseTag: 'topNavTag/removeNavTag'
}),
getMatrixInfo(matrix_id) {
this.formInline = {
matrix_title: '',
matrix_data: [],
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'add',
id: 0,
org_id: 0,
dept_code: 0
}
this.tableColumn = []
this.$http.post('matrix/getMatrixInfo', { id: matrix_id }).then(ress => {
if (ress.status == 200) {
if (ress.data != '') {
this.formInline = ress.data
this.formInline.dotype = 'edit'
this.tableColumn = ress.data.matrix_data_arr
this.productList = ress.data.product_data
console.log(this.productList)
this.fileList = []
if (ress.data.agreement != '') {
var agreement = {
name: ress.data.agreement,
url: ress.data.agreement
}
this.fileList.push(agreement)
}
}
//获取部门组织
this.getSupplierData()
this.getDepts()
}
})
},
getHolesNum(nusds, keyid, typee) {
if (!/^[1-9]\d*$/.test(nusds)) {
ElMessage({
type: 'error',
message: '请输入正整数'
})
this.tableColumn.forEach((item, index) => {
if (keyid == item.keyid) {
if (typee == 1) {
item.holes_num = 0
}
if (typee == 2) {
item.capacity_num = 0
}
}
})
}
},
getMaterialList() {
this.$http.post('matrix/getMaterial').then(ret => {
if (ret.status == 200) {
this.pro_num = ret.data.results
}
})
},
//输入匹配
getMaterial(produce_sn, keyid) {
this.$http.post('matrix/getMaterial', { fnumber: produce_sn }).then(ret => {
if (ret.status == 200) {
if (ret.data.results == '' || ret.data.results == null) {
ElMessage({
type: 'error',
message: '该生产物料编码不存在!'
})
return false
}
this.tableColumn.forEach((item, index) => {
if (keyid == item.keyid) {
if (ret.data.results.FNAME == '') {
item.produce_titile = ''
item.produce_sku = ''
item.produce_id = ''
} else {
item.produce_titile = ret.data.results.FNAME
item.produce_sku = ret.data.results.FSPECIFICATION
item.produce_id = ret.data.results.FMATERIALID
}
}
})
} else {
ElMessage({
type: 'error',
message: '请求错误'
})
}
})
},
getSupplierData() {
this.$http.post('matrix/getSupplier', {}).then(ret => {
this.is_copy_matrixs = ret.data.is_copy_matrixs
this.matrix_type = ret.data.matrix_type
this.matrix_status = ret.data.matrix_status
this.uc_suppliers = ret.data.uc_suppliers
this.uc_orgs = ret.data.uc_orgs
// if (this.matrix_id != '' || this.matrix_id != undifend) {
// this.getMatrixInfo(this.matrix_id)
// }
})
},
//获取部门
getDepts() {
this.$http.get('matrix/getDepts', { org_id: this.formInline.org_id }).then(ret => {
this.depts = ret.data.uc_depts
})
},
//获取员工
getStaff() {
this.$http.get('matrix/getStaffs', { org_id: this.formInline.org_id }).then(ret => {
this.uc_staffs = ret.data.uc_staffs
})
},
//开模申请组织修改后
changeOrg() {
this.formInline.dept_code = '' //重置开模申请部门
this.formInline.matrix_apply = '' //重置开模申请人
//重新获取信息
this.getDepts()
this.getStaff()
},
changeDept(val) {
console.log(val)
this.formInline.dept_code = val[val.length - 1]
},
//获取成品
getProductList() {
//半成品物料为空判断
if (this.tableColumn.length <= 0) {
ElMessage({
type: 'error',
message: '请填写半成品物料'
})
return false
}
this.$http.post('matrix/getProduct', { list: this.tableColumn }).then(ret => {
if (ret.status == 200) {
this.productList = ret.data.results
} else {
ElMessage({
type: 'error',
message: ret.message
})
}
})
},
//删除行
async removeRow(row) {
console.log('row --->', row)
// this.tableColumn.
const $table = this.$refs.xTable
await $table.remove(row)
this.tableColumn.forEach((item, index) => {
if (item.keyid == row.keyid) {
this.tableColumn.splice(index, 1)
}
})
},
// 增加行
async insertEvent(row) {
const $table = this.$refs.xTable
const record = {
id: '',
produce_sn: '',
produce_titile: '',
produce_sku: '',
holes_num: 0,
capacity_num: 0
}
const { row: newRow } = await $table.insertAt(record, row)
await $table.setActiveCell(newRow, 'name')
this.tableColumn.push(newRow)
},
//表格
findList() {
this.loading = true
var that = this
setTimeout(() => {
var list = [{ id: '', produce_sn: '', produce_titile: '', produce_sku: '', holes_num: 0, capacity_num: 0 }]
that.tableColumn = list
this.loading = false
}, 100)
},
authRes() {
this.tableColumn.forEach((item, index) => {
if (item.produce_sku == undefined) {
ElMessage({ type: 'error', message: '可生产物料编码不存在' })
return false
}
// if (item.produce_titile == "" || item.produce_titile == undefined) {
// ElMessage({ type: 'error', message: '物料名称为空' }); return false;
// }
// if (item.produce_sku == "" || item.produce_sku == undefined) {
// ElMessage({ type: 'error', message: '物料规格型号为空' }); return false;
// }
// if (item.holes_num <= 0) {
// ElMessage({ type: 'error', message: '模具穴数需大于0' }); return false;
// }
// if (item.capacity_num <= 0) {
// ElMessage({ type: 'error', message: '模具产能需大于0' }); return false;
// }
})
setTimeout(() => {
this.is_submit = true
}, 500)
},
//保存提交
onSubmit() {
this.authRes()
//获取成品信息 再提交
this.$http.post('matrix/getProduct', { list: this.tableColumn }).then(ret => {
if (ret.status == 200) {
this.productList = ret.data.results
}
if (this.is_submit == true) {
this.formInline.matrix_data = JSON.stringify(this.tableColumn)
this.formInline.product_data = JSON.stringify(this.productList)
this.$http.post('matrix/saveMatrix', this.formInline).then(ret => {
if (ret.status == 200) {
ElMessage({
type: 'success',
message: ret.message
})
const currentPageName = this.$route.name
const tags = this.tags
const idx = tags.findIndex(it => it.name === currentPageName)
if (idx >= 0) {
this.handleCloseTag(idx)
}
this.$router.push({
path: '/mold/index'
})
} else {
ElMessage({
type: 'error',
message: ret.message
})
}
})
}
})
},
//关闭子页面
cancel() {
// let routeData = this.$router.push({
// path: '/mold/index',
// });
// window.opener = null;
// // //新页面中,才能使用如下关闭
// window.close()
this.handleCloseTag()
},
//远程输入框搜索
querySearchAsync(queryString, cb) {
var restaurants = this.restaurants
var results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
cb(results)
}, 3000 * Math.random())
},
createStateFilter(queryString) {
return state => {
return state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
}
},
//上传文件校验
onBeforeUpload(file) {
const isIMAGE = file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'application/pdf' || file.type === 'image/png'
const isLt10M = file.size / 1024 / 1024 < 10
if (!isIMAGE) {
ElMessage({
type: 'error',
message: '上传文件格式错误!'
})
this.fileList = []
}
if (!isLt10M) {
ElMessage({
type: 'error',
message: '超出文件上传大小!'
})
this.fileList = []
}
return isIMAGE && isLt10M
},
handleSelect(item) {
console.log(item)
},
//正负数,含小数
isFloor() {
var obj = event.target
var t = obj.value.charAt(0)
obj.value = obj.value
.replace('.', '$#$') //把第一个字符'.'替换成'$#$'
.replace(/\./g, '') //把其余的字符'.'替换为空
.replace('$#$', '.') //把字符'$#$'替换回原来的'.'
.replace(/[^\d.]/g, '') //只能输入数字和'.'
.replace(/^\./g, '') //不能以'.'开头
.replace(/([0-9]+\.[0-9]{2})[0-9]*/, '$1') //只保留2位小数
if (t == '-') {
obj.value = '-' + obj.value
}
},
//下载
getDownload() {
download(this.formInline.agreement)
},
// 管理上传
handleAvatarSuccess(res, file) {
this.formInline.agreement = res.data.imgpath
},
handleChange(file, fileList) {
this.fileList = fileList.slice(-3)
},
cickCtips(files, fileList) {
ElMessage({
type: 'error',
message: '文件已上传,如要替换请先删除!'
})
}
}
}
</script>
<style scoped>
::v-deep(.vxe-table--render-default .vxe-body--column:not(.col--ellipsis), .vxe-table--render-default .vxe-footer--column:not(.col--ellipsis), .vxe-table--render-default .vxe-header--column:not(.col--ellipsis)) {
padding: 5px 0;
font-size: 12px;
}
::v-deep(.el-form-item__label) {
line-height: 22px;
padding: 8px 12px 12px 0;
font-size: 12px;
}
::v-deep(.vxe-table--main-wrapper) {
font-size: 12px;
}
.mold-header {
margin: 20px;
}
.m-t-20 {
margin: 20px 0;
}
::v-deep(.el-form-item) {
margin-bottom: 20px;
}
.u-t-r {
text-align: right;
}
.click-btn {
width: 100%;
margin: auto;
text-align: center;
}
.btn-save {
width: 150px;
line-height: 28px;
margin-right: 20px;
margin-right: 20px;
}
.btn-cancel {
width: 150px;
line-height: 28px;
}
</style>

414
src/views/mold/index.vue Normal file
View File

@@ -0,0 +1,414 @@
<template>
<div>
<div class="mold-header table_90 f-12">
<el-row>
<!--表单-->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-row :gutter="24">
<el-col :span="5">
<el-form-item label="模具名称" label-width="85px">
<el-input v-model="formInline.matrix_title" placeholder="请输入单个模具名称" maxlength="60" style="width: 100%" oninput="value=value.replace(/[^A-Za-z0-9\u4e00-\u9fa5]/g,'')" @keydown.enter="findList(1)"> </el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="半成品物料编码">
<el-input v-model="formInline.produce_sn" placeholder="请输入单个半成品物料编码或名称" maxlength="60" style="width: 100%" @keydown.enter="findList(1)"> </el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="成品规格型号" label-width="90px">
<el-input v-model="formInline.produce_sku" placeholder="请输入单个成品规格型号" @keydown.enter="findList(1)"> </el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="模具类型" label-width="75px" prop="region">
<el-select v-model="formInline.type" filterable placeholder="全部" style="width: 100%" @keydown.enter="findList(1)">
<el-option label="全部" value="0"></el-option>
<el-option label="塑胶注塑模" value="1"></el-option>
<el-option label="五金模" value="2"></el-option>
<el-option label="硅胶模" value="3"></el-option>
<el-option label="线材模" value="4"></el-option>
<el-option label="铝挤型材模" value="5"></el-option>
<el-option label="金属铸造模" value="6"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="有无复制模" label-width="100px">
<el-select v-model="formInline.is_copy_matrix" filterable placeholder="全部" style="width: 120%" @keydown.enter="findList(1)">
<el-option label="全部" value="0"></el-option>
<el-option label="无" value="1"></el-option>
<el-option label="有,供应商所有" value="2"></el-option>
<el-option label="有,我司所有" value="3"></el-option>
<el-option label="复制模" value="4"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="申请开模时间">
<el-date-picker v-model="formInline.matrix_start" format="YYYY/MM/DD" value-format="YYYY-MM-DD" type="date" placeholder="年/月/日" style="width: 90%" @keydown.enter="findList(1)"> </el-date-picker>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="开模完成时间" label-width="100px">
<el-date-picker v-model="formInline.matrix_finish" type="date" format="YYYY/MM/DD" value-format="YYYY-MM-DD" placeholder="年/月/日" :disabled-date="disabledDate" :shortcuts="shortcuts" style="width: 93%" @keydown.enter="findList(1)"> </el-date-picker>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="开模申请人" @keydown.enter="findList(1)" label-width="90px">
<el-input v-model="formInline.matrix_apply" placeholder="开模申请人" style="width: 100%"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="模具供应商" @keydown.enter="findList(1)">
<el-input v-model="formInline.supplier" placeholder="模具供应商" style="width: 100%"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="物料生产供应商" @keydown.enter="findList(1)">
<el-input v-model="formInline.produc_supplier" placeholder="物料生产供应商" style="width: 120%"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="模具状态" label-width="84px">
<el-select v-model="formInline.status" filterable placeholder="全部" style="width: 92%" @keydown.enter="findList(1)">
<el-option label="全部" value="0"></el-option>
<el-option label="正常" value="1"></el-option>
<el-option label="不佳" value="2"></el-option>
<el-option label="修模" value="3"></el-option>
<el-option label="报废" value="4"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<!-- <el-form-item label="模具剩余寿命" @keydown.enter="findList(1)">
<el-input v-model="formInline.surplus_life_start" placeholder="" style="width:35%;"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/)" maxlength="3">
</el-input> %
<el-input v-model="formInline.surplus_life_end" placeholder="" style="width:35%;"
oninput="this.value = this.value.replace(/[^\d.]/g,'');"></el-input> %
</el-form-item> -->
</el-col>
<el-col :span="13" class="u-t-r">
<el-button type="primary" @click="findList(1)">搜索</el-button>
<el-button type="primary" size="mini" @click="reset()">重置</el-button>
</el-col>
</el-row>
</el-form>
</el-row>
</div>
<!--表格-->
<div class="mold-header">
<el-button type="primary" @click="addClick">新增</el-button>
<el-button type="primary" @click="findList(2)">导出</el-button>
</div>
<div class="bg_white table_90 m-t-10 border-r-10 text-black f-12">
<vxe-table border height="450" :data="tableColumn" empty-text="没有更多数据了" ref="xTable1" :show-overflow="showOverflow1" :export-config="{}">
<vxe-column field="matrix_sn" dir="" fixed="left" align="center" title="模具编号" width="150">
<template #default="{ row }">
<span @click="addEdit(row.id)" class="cus-point">
{{ row.matrix_sn }}
</span>
</template>
</vxe-column>
<vxe-column field="matrix_title" fixed="left" title="模具名称" width="280"></vxe-column>
<vxe-column field="produce_sn" title="半成品物料编码" width="150"></vxe-column>
<vxe-column field="produce_sku" title="成品规格型号sku" width="280"></vxe-column>
<vxe-column field="type_name" title="模具类型" width="100" align="center"></vxe-column>
<vxe-column field="is_copy_matrix_name" title="有无复制模" width="100" align="center"></vxe-column>
<vxe-column field="cost_price" title="模具费用" width="100" align="right"></vxe-column>
<vxe-column field="return_standard" title="模具费返还标准(万次)" width="110" align="right"></vxe-column>
<vxe-column field="matrix_start" title="申请开模时间" width="110"></vxe-column>
<vxe-column field="matrix_finish" title="开模完成时间" width="110"></vxe-column>
<vxe-column field="matrix_life" title="模具设计寿命(万次)" width="110"></vxe-column>
<vxe-column field="holes_num" title="模具穴数" width="83"></vxe-column>
<vxe-column field="capacity_num" title="模具产能(每小时)" width="100"></vxe-column>
<!-- <vxe-column field="surplus_life" title="模具剩余寿命" width="110" align="right" ></vxe-column> -->
<vxe-column field="matrix_apply" title="开模申请人" width="100" align="center"></vxe-column>
<vxe-column field="supplier" title="模具供应商" width="150"></vxe-column>
<vxe-column field="produc_supplier" title="物料生产供应商" width="150"></vxe-column>
<vxe-column field="status_name" title="模具状态" width="83" align="center">
<template #default="{ row }">
<span v-if="row.status == 1" class="green">{{ row.status_name }}</span>
<span v-else-if="row.status == 2" class="yellow">{{ row.status_name }}</span>
<span v-else-if="row.status == 3" class="red">{{ row.status_name }}</span>
<span v-else-if="row.status == 4" class="gray">{{ row.status_name }}</span>
</template>
</vxe-column>
<vxe-column field="agreement" title="模具保管协议" width="105" align="center">
<!--文件图片下载 S-->
<template #default="{ row }">
<vxe-button v-if="row.agreement == ''" disabled status="info">下载</vxe-button>
<vxe-button @click="getDownload(row.agreement)" status="primary" v-else>下载</vxe-button>
</template>
<!--文件图片下载 E-->
</vxe-column>
<vxe-column field="remark" title="备注" width="280">
<template #default="scope">
<el-tooltip effect="dark" :content="scope.row.remark" placement="top" :disabled="scope.row.remark.length > 30">
<span>{{ scope.row.remark }}</span>
</el-tooltip>
</template>
</vxe-column>
</vxe-table>
<!--分页-->
<div class="page-totle">
<el-pagination :current-page="formInline.page" :page-sizes="[10, 20, 30]" :page-size="formInline.size" layout="total, sizes, prev, pager, next, jumper" :total="count" class="m-t-10 m-b-20 table_90" @size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
</div>
</div>
</div>
</template>
<script>
import download from 'downloadjs' //下载依赖
import { ElMessage } from 'element-plus'
import axios from 'axios'
export default {
data() {
return {
tableData: [],
tableColumn: [],
region: [],
showOverflow1: false, //导出
formInline: {
page: 1,
size: 20,
matrix_title: '',
produce_sn: '',
produce_titile: '',
produce_sku: '',
type_name: '',
is_copy_matrix: '',
is_copy_matrix_name: '',
matrix_apply: '',
supplier: '',
produc_supplier: '',
surplus_life_start: '',
matrix_start: '',
matrix_finish: '',
surplus_life_end: '',
status_name: '',
status: '',
export: '',
type: ''
},
value1: '',
value2: '',
conut: ''
}
},
created() {
this.matrix_id = this.$route.query.matrix_id
this.findList()
},
//清除缓存
activated() {
this.matrix_id = this.$route.query.matrix_id
if (this.$route.query.type == 0) {
;(this.fileList = []),
(this.tableColumn = []),
(this.formInline = {
matrix_title: '',
matrix_data: [],
produce_sku: '',
type: '',
is_copy_matrix: '',
cost_price: '',
return_standard: '',
matrix_start: '',
matrix_finish: '',
matrix_life: '',
surplus_life: '',
supplier: '',
status: '',
agreement: '',
remark: '',
matrix_apply: '',
dotype: 'add',
id: 0
})
}
this.findList()
},
//清除缓存
beforeRouteUpdate(to, from, next) {
this.matrix_id = to.query.matrix_id
this.findList()
next()
},
methods: {
//模具列表
findList(type) {
console.log(1111111)
if (type == 1) {
this.formInline.page = 1
}
if (type == 2) {
this.formInline.export = 1
this.batchExport()
return false
}
this.listLoading = true
this.$http.post('matrix/matrixIndex', this.formInline).then(res => {
if (res.status == 200) {
this.tableColumn = res.data.results
this.matrix_type = res.data.matrix_type
this.count = res.data.count_limit
console.log(res.data.result)
} else {
ElMessage({
type: 'error',
message: res.errmsg
})
}
})
},
//批量导出
batchExport() {
/* this.batchExportShow = true*/
const apiVersion = process.env.VUE_APP_API_VERSION.replace(/\./g, '_')
axios
.get(process.env.VUE_APP_API_BASEURL + apiVersion + '/matrix/exportMatrix', {
params: this.formInline,
responseType: 'blob',
headers: {
/*'X-Token': getToken(),*/
'Content-Type': 'application/json;charset=utf-8'
}
})
.then(res => {
if (!res) {
this.$message.error('下载模板文件失败')
return false
}
const stream = res.data // 后端用stream返回Excel文件
const blob = new Blob([stream])
// 前端获取业务码,成功执行正常业务
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
const timeStamp = new Date().toString()
const nameStr = decodeURI(escape(JSON.parse(res.headers['content-disposition'].split(';')[1].split('=')[1])))
downloadElement.download = nameStr // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
},
//重置
reset() {
this.formInline = {
page: 1,
size: 20,
matrix_title: '',
produce_sn: '',
produce_sku: '',
type_name: '',
type: '',
is_copy_matrix: '',
produce_titile: '',
matrix_apply: '',
supplier: '',
produc_supplier: '',
surplus_life_start: '',
surplus_life_end: '',
status_name: ''
}
this.findList()
},
//保留两位小数
numFilter(value) {
const realVal = parseFloat(value).toFixed(2)
return realVal
},
//分页
handleSizeChange(new_size) {
this.formInline.size = new_size
this.findList()
},
handleCurrentChange(new_page) {
this.formInline.page = new_page
this.findList()
},
//新增
addClick() {
this.$router.push({
path: '/mold/add_mold',
query: { type: 0 }
})
},
addEdit(matrix_id) {
this.$router.push({
path: '/mold/edit_mold',
query: { matrix_id: matrix_id }
})
},
//下载
getDownload(agreement) {
download(agreement)
}
}
}
</script>
<style scoped>
::v-deep(.vxe-table--render-default .vxe-body--column:not(.col--ellipsis), .vxe-table--render-default .vxe-footer--column:not(.col--ellipsis), .vxe-table--render-default .vxe-header--column:not(.col--ellipsis)) {
padding: 5px 0;
font-size: 12px;
}
::v-deep(.el-form-item__label, .el-form-item__label) {
font-size: 12px;
}
::v-deep(.vxe-button.type--button) {
height: 24px;
}
::v-deep(.vxe-button) {
font-size: 12px;
}
::v-deep(.vxe-body--row:hover) {
background: #f9f9f9;
}
.f-12 {
font-size: 12px;
}
.cus-point {
cursor: pointer;
color: #2c74fa;
}
.cus-point:hover {
color: #2c74fa;
}
.green {
color: #38b48b;
}
.yellow {
color: #fb941c;
}
.red {
color: #ff3000;
}
.gray {
color: #909090;
}
.mold-header {
margin: 20px;
}
.u-t-r {
text-align: right;
}
::v-deep(.el-button) {
min-height: 34px;
padding: 6px 20px;
}
.page-totle {
width: 100%;
text-align: right;
}
::v-deep(.vxe-table--render-default .vxe-cell) {
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

12
src/views/public/404.vue Normal file
View File

@@ -0,0 +1,12 @@
<template>
<el-main>404</el-main>
</template>
<style lang="scss" scoped>
</style>
<script>
export default {
data () {
return {}
}
}
</script>