<template>
|
<div class="main">
|
<div class="inner" ref="wraper">
|
<a-spin class="" :spinning="spinning" tip="拼命加载中...">
|
<a-card>
|
<advance-table
|
ref="table"
|
class="doc-center-table"
|
:data-source="dataSource"
|
:columns="columns"
|
:loading="loading"
|
title=""
|
row-key="id"
|
@search="onSearch"
|
@refresh="onRefresh"
|
@reset="onReset"
|
:format-conditions="true"
|
:scroll="{ x: 400, y }"
|
:pagination="{
|
current: pageCurr,
|
pageSize: pageSize,
|
total: total,
|
showSizeChanger: true,
|
showLessItems: true,
|
showQuickJumper: true,
|
pageSizeOptions: ['10', '20', '50', '100'],
|
showTotal: (total, range) =>
|
`第 ${range[0]}-${range[1]} 条,总计 ${total} 条`,
|
onChange: onPageChange,
|
onShowSizeChange: onSizeChange,
|
}"
|
:rowClassName="rowClassFn"
|
>
|
<template slot="dataIndex" slot-scope="{ index }">
|
{{ index + 1 }}
|
</template>
|
<template slot="title">
|
<a-space class="operator">
|
<span class="title">产品中心</span>
|
<a-button v-if="canUploadBom" type="primary" @click="uploadBom"
|
>新增</a-button
|
>
|
<a-button type="primary" @click="prodDiff">产品比较</a-button>
|
<a-button type="primary" @click="ownerDownloadLog"
|
>我的锁定记录</a-button
|
>
|
</a-space>
|
</template>
|
<template slot="enabled" slot-scope="{ record }">
|
{{ record.enabled == -1 ? "是" : "否" }}
|
</template>
|
<template slot="enabled1" slot-scope="{ record }">
|
{{ record.enabled == 1 ? "可用" : "不可用" }}
|
</template>
|
<template slot="isNormal" slot-scope="{ record }">
|
{{ record.customCode == "" ? "是" : "否" }}
|
</template>
|
<template slot="action" slot-scope="{ record }">
|
<!-- <template v-if="canUploadSoftware">
|
<a @click="upload(record)">上传软件</a>
|
<a-divider type="vertical"></a-divider>
|
</template> -->
|
<a @click="viewLog(record)">状态日志</a>
|
<a-divider type="vertical"></a-divider>
|
<a @click="goDetails(record)">详情</a>
|
<a-divider type="vertical"></a-divider>
|
<a-popover title="" trigger="hover">
|
<a-space class="btn-grp" direction="vertical" slot="content">
|
<!-- TODO -->
|
<a-button
|
v-if="isTester && record.enabled != 1"
|
type="primary"
|
@click="unLock(record)"
|
>解锁</a-button
|
>
|
<a-button type="primary" @click="downloadLog(record)"
|
>下载日志</a-button
|
>
|
<a-button
|
:disabled="record.version != 1"
|
type="primary"
|
@click="edit(record)"
|
>编辑</a-button
|
>
|
<a-button
|
v-if="canDownloadBom"
|
:disabled="record.version == -1 && !isTester"
|
type="primary"
|
@click="checkLock(record)"
|
>下载</a-button
|
>
|
<a-button
|
type="primary"
|
v-if="canUploadBom"
|
:disabled="record.version == -1"
|
@click="showCustom(record)"
|
>定制</a-button
|
>
|
<a-button
|
type="primary"
|
v-if="canFeedback"
|
@click="showFeedback(record)"
|
>反馈</a-button
|
>
|
<a-badge
|
:count="record.ecrList.length"
|
showZero
|
:number-style="{
|
backgroundColor: record.ecrList.length > 0 ? '#090' : '#900',
|
}"
|
>
|
<a-button
|
type="primary"
|
@click="showEcrlist(record)"
|
>ecr记录</a-button
|
>
|
</a-badge>
|
</a-space>
|
<a>更多</a>
|
</a-popover>
|
</template>
|
</advance-table>
|
</a-card>
|
</a-spin>
|
</div>
|
<!-- 上传软件 -->
|
<a-modal
|
:visible="uploadShow"
|
:footer="null"
|
:width="500"
|
title="上传软件"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="uploadCancel"
|
>
|
<div class="">
|
<a-row class="title">
|
<a-col :span="6" class="text-right">
|
<span>产品信息</span>
|
</a-col>
|
<a-col :span="15" :offset="1">
|
<div class="lab">
|
{{ prodData.parentModel }} {{ prodData.parentName }}
|
</div>
|
</a-col>
|
</a-row>
|
<a-row class="upload">
|
<a-col :span="15" :offset="7">
|
<a-upload
|
:before-upload="beforeUpload"
|
@change="uploadChange"
|
accept=".zip"
|
>
|
<a-button type="primary">上传软件</a-button>
|
</a-upload>
|
</a-col>
|
</a-row>
|
<a-form-model
|
ref="formRef"
|
name="advanced_search"
|
class="ant-advanced-search-form"
|
:model="info"
|
:rules="rules"
|
>
|
<a-row>
|
<a-col :span="24">
|
<a-form-model-item
|
label="审核人"
|
:labelCol="{ span: 6 }"
|
:wrapperCol="{ span: 15, offset: 1 }"
|
prop="nextUser"
|
>
|
<a-select
|
show-search
|
v-model="info.nextUser"
|
placeholder="请选择审核人"
|
>
|
<a-select-option
|
v-for="(item, key) in userList"
|
:key="'key' + key"
|
:value="item.id"
|
:title="item.name"
|
>
|
{{ item.name }}
|
</a-select-option>
|
</a-select>
|
</a-form-model-item>
|
</a-col>
|
<a-col :span="24">
|
<a-form-model-item
|
label="工单描述"
|
:labelCol="{ span: 6 }"
|
:wrapperCol="{ span: 15, offset: 1 }"
|
prop="description"
|
>
|
<a-textarea
|
placeholder="请输入工单描述"
|
v-model="info.description"
|
:rows="4"
|
/>
|
</a-form-model-item>
|
</a-col>
|
</a-row>
|
</a-form-model>
|
<div class="modal-footer">
|
<a-button type="danger" @click="uploadCancel"> 取消 </a-button>
|
<a-button type="primary" @click="uploadSoftware"> 提交审核 </a-button>
|
</div>
|
</div>
|
</a-modal>
|
<!-- 编辑产品 -->
|
<a-modal
|
:visible="editShow"
|
:footer="null"
|
:width="1200"
|
title="修改产品替换件信息"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="cancel"
|
>
|
<change-parts :parent-data="editObj" @close="cancel"></change-parts>
|
</a-modal>
|
<!-- 上传bom -->
|
<a-modal
|
:visible="bomUploadShow"
|
:width="760"
|
title="上传产品BOM"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="bomUploadCancel"
|
@ok="bomUploadOk"
|
>
|
<a-row class="upload" type="flex">
|
<a-col flex="7em"></a-col>
|
<a-col flex="1">
|
<a-upload
|
:before-upload="beforeUpload"
|
@change="uploadChange"
|
accept=".zip"
|
>
|
<a-button type="primary">上传BOM</a-button>
|
</a-upload>
|
</a-col>
|
</a-row>
|
<a-row type="flex">
|
<a-col class="label" flex="7em"><span>基于产品</span></a-col>
|
<a-col flex="1">
|
<a-select
|
class="from"
|
show-search
|
allowClear
|
:filterOption="prodFilter"
|
v-model="fromProd"
|
placeholder="请选择是从哪款产品升级来的"
|
>
|
<a-select-option
|
v-for="(item, key) in prodList"
|
:key="'prod_' + key"
|
:value="item.id"
|
:title="item.name"
|
>
|
{{ item.parentName }} ({{ item.parentCode }})
|
{{ item.customCode }}
|
</a-select-option>
|
</a-select>
|
</a-col>
|
</a-row>
|
</a-modal>
|
<!-- 解析Bom -->
|
<a-modal
|
:visible="prodUploadShow"
|
:footer="null"
|
:width="960"
|
title="上传产品BOM"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="prodUploadCancel"
|
>
|
<a-tabs type="card" tabPosition="left">
|
<a-tab-pane key="1" tab="清单">
|
<draw-upload
|
class="bom-list"
|
:list="resList"
|
:y="320"
|
:no-footer="true"
|
></draw-upload>
|
</a-tab-pane>
|
<a-tab-pane key="2" tab="差异">
|
<diff-list :list="diffData"></diff-list>
|
</a-tab-pane>
|
<a-tab-pane key="3" :tab="abLabel">
|
<a-table
|
ref="aTable"
|
size="small"
|
:scroll="{ y: 700 }"
|
bordered
|
:columns="abTbl.columns"
|
:data-source="abTbl.dataSource"
|
:pagination="false"
|
rowKey="subCode"
|
></a-table>
|
<div style="text-align: right; padding: 8px">
|
<a-button
|
@click="abTbl.ignore = true"
|
:type="abState ? 'danger' : 'primary'"
|
:icon="abState ? 'question' : 'check'"
|
>{{ abState ? "未确认" : "已确认" }}</a-button
|
>
|
</div>
|
</a-tab-pane>
|
<a-tab-pane key="4" :tab="errorLabel">
|
<a-table
|
ref="aTable"
|
size="small"
|
:scroll="{ y: 700 }"
|
bordered
|
:columns="errorTbl.columns"
|
:data-source="errorTbl.dataSource"
|
:pagination="false"
|
rowKey="subCode"
|
></a-table>
|
</a-tab-pane>
|
</a-tabs>
|
<prod-upload
|
class="mt8"
|
@ok="submit"
|
@cancel="prodUploadCancel"
|
></prod-upload>
|
</a-modal>
|
<!-- 定制 -->
|
<a-modal
|
:visible="customShow"
|
:footer="null"
|
:width="800"
|
title="产品定制"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="customCancel"
|
>
|
<prod-upload
|
class="mt8"
|
:prod-info="customProd"
|
@ok="custom"
|
@cancel="customCancel"
|
></prod-upload>
|
</a-modal>
|
<!-- 日志 -->
|
<a-modal
|
:visible="logVisible"
|
:footer="null"
|
:width="800"
|
title="操作日志"
|
:destroyOnClose="true"
|
@cancel="logCancel"
|
>
|
<div class="log-content">
|
<a-timeline v-if="logList.length">
|
<a-timeline-item
|
v-for="(item, idx) in logList"
|
:key="'log_' + idx"
|
:color="item.lockFlag == 1 ? 'red' : 'green'"
|
>
|
<div>
|
<span class="user">{{ item.owner }}</span> 在
|
<span class="time">{{ item.createTime }}</span>
|
{{
|
{ "-1": "上传", "0": "激活", "1": "锁定" }[item.lockFlag]
|
}}了版本
|
<span class="version">{{ item.versionTime }}</span>
|
</div>
|
<div>操作原因: {{ item.reason ? item.reason : "无" }}</div>
|
</a-timeline-item>
|
</a-timeline>
|
<a-empty v-else />
|
</div>
|
</a-modal>
|
<!-- 锁定清单 -->
|
<a-modal
|
:visible="lockListVisible"
|
:width="800"
|
title="下载提示 (有锁定文件)"
|
:destroyOnClose="true"
|
@cancel="lockListCancel"
|
@ok="lockListOk"
|
>
|
<!-- bom清单中存在锁定图纸的物料 -->
|
<template v-if="bomLockList.length">
|
<div class="table-title">bom清单中存在锁定图纸的物料</div>
|
<a-table
|
size="small"
|
:scroll="{ y: 150 }"
|
bordered
|
:columns="bomLockColumns"
|
:data-source="bomLockList"
|
:pagination="false"
|
:expandRowByClick="true"
|
:row-key="(record, index) => index"
|
></a-table>
|
</template>
|
<!-- 其他附件中存在锁定文件 -->
|
<template v-if="otherLockList.length">
|
<div class="table-title">其他附件中存在锁定文件</div>
|
<a-table
|
size="small"
|
:scroll="{ y: 150 }"
|
bordered
|
:columns="otherLockColumns"
|
:data-source="otherLockList"
|
:pagination="false"
|
:expandRowByClick="true"
|
:row-key="(record, index) => index"
|
></a-table>
|
</template>
|
</a-modal>
|
<a-modal
|
:visible="feedbackShow"
|
:width="800"
|
title="问题反馈"
|
:destroyOnClose="true"
|
:footer="false"
|
@cancel="feedbackCancel"
|
>
|
<feedback-form
|
:prod-data="customProd"
|
@cancel="feedbackCancel"
|
@ok="feedbackOk"
|
></feedback-form>
|
</a-modal>
|
<!-- ecr列表 -->
|
<a-modal
|
:visible="ecrListVisible"
|
:width="800"
|
title="ecr记录"
|
:destroyOnClose="true"
|
@cancel="ecrListCancel"
|
>
|
<div class="footer" slot="footer">
|
<a-button type="primary" @click="ecrListCancel">关闭</a-button>
|
</div>
|
<div class="ecr-content">
|
<a-table
|
ref="aTable"
|
size="small"
|
:scroll="{ y: 700 }"
|
bordered
|
:columns="ecrColumns"
|
:data-source="ecrList"
|
:pagination="false"
|
rowKey="id"
|
>
|
<template slot="changeDesc" slot-scope="text, record">
|
<a-tooltip placement="topLeft">
|
<template slot="title">
|
{{ record.changeDescription }}
|
</template>
|
{{ record.changeDescription }}
|
</a-tooltip>
|
</template>
|
</a-table>
|
</div>
|
</a-modal>
|
<a-modal
|
:visible="errorVisible"
|
:footer="null"
|
:width="1200"
|
title="名称或型号命名不规范"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="errorVisible = false"
|
>
|
<a-table
|
ref="aTable"
|
size="small"
|
:scroll="{ y: 500 }"
|
bordered
|
:columns="errorTbl2.columns"
|
:data-source="errorTbl2.dataSource"
|
:pagination="false"
|
rowKey="num"
|
></a-table>
|
</a-modal>
|
<!-- 操作原因 -->
|
<a-modal
|
:visible="reasonVisible"
|
:width="460"
|
title="操作原因"
|
:destroyOnClose="true"
|
:maskClosable="false"
|
@cancel="reasonCancel"
|
@ok="reasonOk"
|
>
|
<a-form-model-item ref="name" label="操作原因">
|
<a-input
|
type="textarea"
|
v-model="reason"
|
placeHolder="请输入操作原因"
|
/>
|
</a-form-model-item>
|
</a-modal>
|
<download-reason
|
:reason-visible.sync="downloadReasonVisible"
|
v-if="downloadReasonVisible"
|
@ok="downloadReasonOk"
|
></download-reason>
|
<download-logs
|
:visible.sync="downloadlogVisible"
|
v-if="downloadlogVisible"
|
:type="12"
|
:oprate-info="oprateInfo"
|
></download-logs>
|
<a-modal
|
:visible="ownerLogVisible"
|
title="我的下载记录"
|
width="100%"
|
:destroyOnClose="true"
|
@cancel="ownerLogClose"
|
wrapClassName="full-modal"
|
>
|
<owner-download></owner-download>
|
<template v-slot:footer>
|
<a-button @click="ownerLogClose">关闭</a-button>
|
</template>
|
</a-modal>
|
</div>
|
</template>
|
|
<script>
|
import AdvanceTable from "@/components/table/advance/AdvanceTable";
|
import ChangeParts from "./changeParts";
|
import ProdUpload from "./prodUpload";
|
import DrawUpload from "@/pages/components/drawUpload";
|
import DownloadReason from "@/pages/components/downloadReason";
|
import DownloadLogs from "@/pages/components/downloadLogs";
|
|
import getWebUrl from "@/assets/js/tools/getWebUrl";
|
import {
|
addProduct,
|
downloadBom,
|
getAllProducts,
|
getLogList,
|
getLockedList,
|
setpHistoryEnable,
|
} from "./apis";
|
|
import {
|
searchDefaultMailUser,
|
sendMail,
|
} from "../../components/emailCard/apis";
|
import { getUserList } from "../../permission/apis";
|
|
import { getRoleUser } from "@/pages/user/apis";
|
import { submitFeedback } from "@/pages/workplace/apis";
|
import { productSoftwareSubmit } from "../software/apis";
|
import { zipParse } from "@/pages/workplace/myDraw/apis";
|
import { mapGetters } from "vuex";
|
import checkPermit from "@/assets/js/tools/checkPermit";
|
import PERMITS from "@/assets/js/const/const_permits";
|
|
import createWs from "@/assets/js/websocket";
|
import DiffList from "@/pages/components/diffList";
|
import FeedbackForm from "../components/feedbackForm.vue";
|
import OwnerDownload from "../components/ownerDownload";
|
const WSMixin = createWs("product");
|
|
export default {
|
name: "",
|
mixins: [WSMixin],
|
data() {
|
const abColumns = [
|
{
|
title: "子件编码",
|
dataIndex: "subCode",
|
width: 120,
|
align: "center",
|
},
|
{
|
title: "子件名称",
|
dataIndex: "subName",
|
align: "center",
|
ellipsis: true,
|
},
|
{
|
title: "子件型号",
|
dataIndex: "subModel",
|
align: "center",
|
ellipsis: true,
|
},
|
];
|
const errorColumns = [
|
{
|
title: "子件编码",
|
dataIndex: "subCode",
|
width: 120,
|
align: "center",
|
},
|
{
|
title: "子件名称",
|
dataIndex: "subName",
|
align: "center",
|
ellipsis: true,
|
},
|
{
|
title: "子件型号",
|
dataIndex: "subModel",
|
align: "center",
|
ellipsis: true,
|
},
|
];
|
const ecrColumns = [
|
{
|
title: "流水号",
|
dataIndex: "number",
|
width: 120,
|
align: "center",
|
},
|
{
|
title: "申请人",
|
dataIndex: "proposer",
|
align: "center",
|
ellipsis: true,
|
},
|
{
|
title: "申请日期",
|
dataIndex: "proposeWebsocket",
|
align: "center",
|
ellipsis: true,
|
},
|
{
|
title: "创建时间",
|
dataIndex: "createTime",
|
width: 120,
|
align: "center",
|
},
|
{
|
title: "处理方式",
|
dataIndex: "solution",
|
align: "center",
|
ellipsis: true,
|
},
|
{
|
title: "变更原因",
|
dataIndex: "changeDescription",
|
align: "center",
|
ellipsis: true,
|
scopedSlots: { customRender: "changeDesc" },
|
},
|
];
|
return {
|
ownerLogVisible: false,
|
reason: "",
|
reasonVisible: false,
|
oprateInfo: "",
|
downloadlogVisible: false,
|
tester: [],
|
downloadReasonVisible: false,
|
curObj: null,
|
errorVisible: false,
|
ecrColumns,
|
feedbackShow: false,
|
lockListVisible: false,
|
currentObj: null,
|
bomLockList: [],
|
otherLockList: [],
|
ecrList: [],
|
ecrListVisible: false,
|
logVisible: false,
|
logList: [],
|
fromProd: undefined,
|
prodList: [],
|
diffData: {},
|
bomUploadShow: false,
|
prodUploadShow: false,
|
info: {
|
nextUser: "",
|
description: "",
|
},
|
rules: {
|
nextUser: [
|
{
|
required: true,
|
message: "请选择审核人",
|
trigger: "blur",
|
},
|
],
|
},
|
prodData: {},
|
userList: [],
|
userListAll: [],
|
mailList: [],
|
file: null,
|
// title: "",
|
fileUrl: "",
|
resList: [],
|
uploadShow: false,
|
customShow: false,
|
customProd: null,
|
editShow: false,
|
editObj: undefined,
|
selectedRowKeys: [],
|
selectedRows: [],
|
spinning: false,
|
loading: false,
|
pageCurr: 1,
|
pageSize: 10,
|
total: 0,
|
y: 400,
|
update: -1,
|
webUrl: getWebUrl(),
|
conditions: {},
|
columns: [
|
{
|
fixed: "left",
|
title: "序号",
|
dataIndex: "dataIndex",
|
key: "dataIndex",
|
align: "center",
|
width: 60,
|
noSearch: true,
|
scopedSlots: { customRender: "dataIndex" },
|
},
|
{
|
title: "编号",
|
dataIndex: "parentCode",
|
key: "parentCode",
|
width: 130,
|
align: "center",
|
searchAble: true,
|
},
|
{
|
title: "型号",
|
dataIndex: "parentModel",
|
key: "parentModel",
|
align: "center",
|
width: 180,
|
searchAble: true,
|
},
|
{
|
title: "名称",
|
dataIndex: "parentName",
|
key: "parentName",
|
align: "center",
|
width: 180,
|
searchAble: true,
|
},
|
{
|
title: "定制单号",
|
dataIndex: "customCode",
|
key: "customCode",
|
align: "center",
|
width: 160,
|
searchAble: true,
|
},
|
{
|
title: "标准机型",
|
dataIndex: "isNormal",
|
dataType: "boolean",
|
align: "center",
|
searchAble: true,
|
width: 100,
|
scopedSlots: { customRender: "isNormal" },
|
},
|
{
|
title: "待复核",
|
dataIndex: "enabled",
|
dataType: "boolean",
|
align: "center",
|
searchAble: true,
|
width: 100,
|
scopedSlots: { customRender: "enabled" },
|
},
|
{
|
title: "是否可用",
|
dataIndex: "enabled1",
|
dataType: "boolean",
|
align: "center",
|
searchAble: false,
|
width: 100,
|
scopedSlots: { customRender: "enabled1" },
|
},
|
// {
|
// title: "创建时间",
|
// dataIndex: "createTime",
|
// key: "createTime",
|
// align: "center",
|
// noSearch: true,
|
// width: 160,
|
// },
|
{
|
title: "子件编码",
|
dataIndex: "subCode",
|
align: "center",
|
searchAble: true,
|
visible: false,
|
},
|
{
|
title: "版本时间",
|
dataIndex: "versionTime",
|
key: "versionTime",
|
align: "center",
|
noSearch: true,
|
width: 160,
|
},
|
{
|
title: "操作",
|
dataIndex: "operation",
|
key: "operation",
|
align: "center",
|
width: 228,
|
fixed: "right",
|
scopedSlots: { customRender: "action" },
|
noSearch: true,
|
},
|
],
|
dataSource: [],
|
abTbl: {
|
ignore: false,
|
columns: abColumns,
|
dataSource: [],
|
},
|
errorTbl: {
|
columns: errorColumns,
|
dataSource: [],
|
},
|
errorTbl2: {
|
columns: [
|
{
|
title: "子件编码",
|
dataIndex: "subCode",
|
align: "center",
|
},
|
{
|
title: "子件型号",
|
dataIndex: "subModel",
|
align: "center",
|
},
|
{
|
title: "子件名称",
|
dataIndex: "subName",
|
align: "center",
|
},
|
{
|
title: "问题描述",
|
dataIndex: "irregularDesc",
|
align: "center",
|
},
|
],
|
dataSource: [],
|
},
|
bomLockColumns: [
|
{
|
title: "子件名称",
|
dataIndex: "subName",
|
align: "center",
|
},
|
{
|
title: "文件名称",
|
dataIndex: "attachName",
|
align: "center",
|
},
|
{
|
title: "锁定说明",
|
dataIndex: "localReason",
|
align: "center",
|
},
|
],
|
otherLockColumns: [
|
{
|
title: "文件名称",
|
dataIndex: "attachName",
|
align: "center",
|
},
|
{
|
title: "锁定说明",
|
dataIndex: "localReason",
|
align: "center",
|
},
|
],
|
};
|
},
|
components: {
|
AdvanceTable,
|
ChangeParts,
|
ProdUpload,
|
DrawUpload,
|
DiffList,
|
FeedbackForm,
|
DownloadReason,
|
DownloadLogs,
|
OwnerDownload,
|
},
|
methods: {
|
rowClassFn(record) {
|
let classList = [];
|
if (record.enabled == -1) {
|
classList.push("locked");
|
}
|
if (record.enabled == 0) {
|
classList.push("unable");
|
}
|
return classList;
|
},
|
unLock(obj) {
|
this.curObj = obj;
|
this.reasonVisible = true;
|
},
|
reasonCancel() {
|
this.reasonVisible = false;
|
},
|
reasonOk() {
|
let {
|
curObj: {
|
customCode,
|
parentCode,
|
version,
|
versionTime,
|
enabled: lockFlagNow,
|
},
|
reason,
|
} = this;
|
let enabled = 1;
|
setpHistoryEnable({
|
customCode,
|
parentCode,
|
enabled,
|
version,
|
reason,
|
versionTime,
|
}).then((res) => {
|
let { code, data } = res.data;
|
if (code && data) {
|
this.$message.success("操作成功");
|
this.sendMessage();
|
this.reasonVisible = false;
|
// 如果是测试人员解锁确认 则自动发送邮件
|
if (lockFlagNow == -1 && this.isTester) {
|
this.sendEmail();
|
}
|
} else {
|
this.$message.error("操作失败");
|
}
|
});
|
},
|
sendEmail() {
|
let { title, content } = this.handleEmailShow(this.curObj, true);
|
let params = { mailList: this.mailList, title, content };
|
sendMail(params);
|
},
|
searchAllUserList() {
|
getUserList()
|
.then((res) => {
|
let rs = res.data;
|
if (rs.code && rs.data) {
|
this.userListAll = rs.data2;
|
this.searchDefaultMailUser();
|
}
|
})
|
.catch((error) => {
|
console.log(error);
|
});
|
},
|
searchDefaultMailUser() {
|
// type为3
|
let type = 3;
|
searchDefaultMailUser(type).then((res) => {
|
let rs = res.data;
|
let data = [];
|
if (rs.code === 1) {
|
data = rs.data.map((item) => {
|
return item.user;
|
});
|
}
|
this.mailList = this.userListAll
|
.filter((o) => data.includes(o.name) && o.mail)
|
.map((item) => {
|
return item.mail;
|
});
|
});
|
},
|
handleEmailShow(record, get) {
|
let title =
|
"[产品发布记录]" + record.parentModel + " 版本:" + record.versionTime;
|
let content = [];
|
content.push("物料编码: " + record.parentCode);
|
content.push("物料名称: " + record.parentName);
|
content.push("规格型号: " + record.parentModel);
|
content.push("标准机型: " + (!record.customCode ? "是" : "否"));
|
content.push("定制单号: " + (record.customCode || "无"));
|
content.push("版本时间: " + record.versionTime);
|
if (get) {
|
return {
|
title,
|
content: content.join("\n"),
|
};
|
}
|
},
|
onSearch(conditions, searchOptions) {
|
// console.log(conditions);
|
// console.log(searchOptions);
|
this.pageCurr = 1;
|
this.conditions = conditions;
|
this.sendMessage();
|
},
|
onPageChange(page, pageSize) {
|
this.pageCurr = page;
|
this.pageSize = pageSize;
|
this.sendMessage();
|
},
|
onSizeChange(current, size) {
|
this.pageCurr = 1;
|
this.pageSize = size;
|
this.sendMessage();
|
},
|
onRefresh(conditions) {
|
this.conditions = conditions;
|
this.sendMessage();
|
},
|
onReset(conditions) {
|
this.conditions = conditions;
|
this.sendMessage();
|
},
|
goDetails(record) {
|
// console.log(record);
|
const { parentCode, customCode, parentModel, parentName } = record;
|
let is0120 = /^0120/.test(parentCode);
|
this.$router.push({
|
path: is0120
|
? "/resource/product-details-0120"
|
: "/resource/product-details",
|
query: { parentCode, customCode, parentModel, parentName },
|
});
|
},
|
searchData(res) {
|
if (res) {
|
// res = res.data;
|
// console.log(res, "======");
|
let data = [];
|
let total = 0;
|
if (res.code && res.data) {
|
data = res.data2.list.map((v) => {
|
if ("" != v.customCode) {
|
v.ecrList = [];
|
}
|
return v;
|
});
|
total = res.data2.total;
|
}
|
this.dataSource = data;
|
this.total = total;
|
if (-1 == this.update) {
|
this.update = Math.random();
|
}
|
}
|
},
|
edit(obj) {
|
// console.log(obj, 99);
|
this.editObj = obj;
|
this.editShow = true;
|
},
|
checkLock(obj) {
|
let loading = this.$layer.loading({ shade: true });
|
getLockedList(obj.id).then((res) => {
|
const { code, data, data2, data3 } = res.data;
|
this.$layer.close(loading);
|
if (code) {
|
if (data) {
|
// 有锁定
|
this.currentObj = obj;
|
this.bomLockList = data2;
|
this.otherLockList = data3;
|
this.lockListVisible = true;
|
} else {
|
// 没有锁定
|
this.showReason(obj);
|
}
|
} else {
|
this.$message.error("查询锁定清单出错");
|
}
|
});
|
},
|
lockListCancel() {
|
this.lockListVisible = false;
|
},
|
lockListOk() {
|
this.lockListVisible = false;
|
this.showReason(this.currentObj);
|
},
|
showReason(obj) {
|
this.curObj = obj;
|
this.downloadReasonVisible = true;
|
},
|
downloadReasonOk(reason) {
|
this.download(reason);
|
},
|
download(reason) {
|
const { id, version, parentCode, customCode } = this.curObj;
|
let oprateInfo = parentCode + "_" + customCode;
|
let loading = this.$layer.loading({ shade: true });
|
downloadBom(id, version, reason, oprateInfo).then((res) => {
|
// console.log(res, "===========");
|
this.$layer.close(loading);
|
let { headers, data, status } = res;
|
if (200 == status && data) {
|
let url = window.URL.createObjectURL(data);
|
const matchRes = /filename=(.*)/.exec(headers["content-disposition"]);
|
const fileName = matchRes
|
? decodeURI(matchRes[1].trim())
|
: "未知文件名.zip";
|
let link = document.createElement("a");
|
link.style.display = "none";
|
link.href = url;
|
link.download = fileName;
|
document.body.appendChild(link);
|
link.click();
|
document.body.removeChild(link);
|
window.URL.revokeObjectURL(url);
|
} else {
|
this.$message.error("操作失败");
|
}
|
});
|
},
|
beforeUpload() {
|
return false;
|
},
|
uploadSoftware() {
|
let obj = {
|
approving: {
|
parentModel: this.prodData.parentModel,
|
},
|
main: {
|
nextUser: this.info.nextUser,
|
title: `为产品${this.prodData.parentModel}上传软件`,
|
description: this.info.description,
|
},
|
};
|
if (!this.file) {
|
this.$message.warning("请选择要上传的软件包");
|
return false;
|
}
|
this.$refs.formRef.validate((valid) => {
|
if (!valid) {
|
this.$message.error("存在未通过检验的表单项");
|
return false;
|
} else {
|
const formData = new FormData();
|
formData.append("multipartFile", this.file);
|
formData.append("mainDTOString", JSON.stringify(obj));
|
|
let loading = this.$layer.loading({ shade: true });
|
productSoftwareSubmit(formData)
|
.then((res) => {
|
this.$layer.close(loading);
|
let rs = res.data;
|
if (rs.code == 1 && rs.data) {
|
this.resList = rs.data2;
|
this.title = rs.data3;
|
this.resShow = true;
|
this.$message.success(rs.msg);
|
} else {
|
this.$message.error(rs.msg);
|
}
|
})
|
.catch((error) => {
|
this.$layer.close(loading);
|
console.log(error);
|
});
|
}
|
});
|
},
|
upload(record) {
|
this.prodData = record;
|
this.file = null;
|
this.uploadShow = true;
|
},
|
uploadChange(data) {
|
const { file, fileList } = data;
|
if (fileList.length > 1) {
|
fileList.shift();
|
// console.log(file, fileList, "90909090");
|
}
|
if (fileList.length) {
|
// this.file = fileList[0];
|
// console.log(file == fileList[0], file == fileList[0].originFileObj)
|
this.file = fileList[0].originFileObj;
|
} else {
|
this.file = null;
|
}
|
},
|
uploadCancel() {
|
this.uploadShow = false;
|
},
|
cancel() {
|
this.editShow = false;
|
},
|
resize() {
|
setTimeout(() => {
|
this.update = Math.random();
|
}, 200);
|
},
|
onWSOpen() {
|
this.$nextTick(() => {
|
this.sendMessage();
|
});
|
},
|
sendMessage() {
|
if (!this.isWSOpen) {
|
return false;
|
}
|
const { pageCurr, pageSize, conditions, columns } = this;
|
let params = {};
|
let col, index;
|
Object.keys(conditions).forEach((v) => {
|
switch (v) {
|
case "isNormal":
|
if (conditions[v]) {
|
params["customCode"] = "";
|
columns.forEach((val, idx) => {
|
if (val.dataIndex == "customCode") {
|
col = { ...val, search: { value: "", backup: "" } };
|
index = idx;
|
}
|
});
|
this.$set(this.columns, index, col);
|
}
|
break;
|
case "customCode":
|
if (params["customCode"] == undefined) {
|
params[v] = conditions[v];
|
}
|
break;
|
case "enabled":
|
if (conditions[v]) {
|
params[v] = -1;
|
}
|
break;
|
default:
|
params[v] = conditions[v];
|
break;
|
}
|
});
|
let data = {
|
pageSize,
|
pageCurr,
|
...params,
|
};
|
// console.log("=====9=", data, JSON.stringify(data));
|
this.SOCKET.send(JSON.stringify(data));
|
},
|
onWSMessage(res) {
|
res = JSON.parse(res.data);
|
// // console.log(res, "=====111data");
|
this.searchData(res);
|
},
|
getUserByRoleId() {
|
if (this.roles[0].id == 1002) {
|
this.userList = this.generalManagerList.map((item) => item);
|
} else {
|
this.userList = this.projectManagerList.map((item) => item);
|
}
|
},
|
prodUploadCancel() {
|
this.prodUploadShow = false;
|
},
|
submit(data) {
|
if (this.submitState.code) {
|
this.$layer.msg(this.submitState.msg);
|
return;
|
}
|
let loading = this.$layer.loading();
|
// console.log(data);
|
const { parentCode, parentModel, parentName, bomList } = this.resList;
|
const param = {
|
versionTime: data.versionTime,
|
bomList: bomList.map((v) => ({ ...v, id: undefined })),
|
fileUrl: this.fileUrl,
|
customCode: data.customCode,
|
id: this.fromProd,
|
parentCode,
|
parentModel,
|
parentName,
|
};
|
addProduct(param).then((res) => {
|
const { code, data, msg } = res.data;
|
this.$layer.close(loading);
|
if (code && data) {
|
this.$message.success(msg);
|
this.prodUploadShow = false;
|
} else {
|
this.$message.error(msg);
|
}
|
});
|
},
|
showCustom(obj) {
|
this.customProd = obj;
|
this.customShow = true;
|
},
|
showFeedback(obj) {
|
this.customProd = obj;
|
this.feedbackShow = true;
|
},
|
feedbackCancel() {
|
this.feedbackShow = false;
|
},
|
feedbackOk(data) {
|
let {
|
content,
|
multipartFile,
|
productId,
|
receiverIds,
|
receiverNames,
|
senderId,
|
subVersion,
|
} = data;
|
let loading = this.$layer.loading({ shade: true });
|
const formData = new FormData();
|
multipartFile.forEach((v) => {
|
formData.append("multipartFileList", v);
|
});
|
formData.append(
|
"feedbackJson",
|
JSON.stringify({
|
content,
|
productId,
|
receiverIds,
|
receiverNames,
|
senderId,
|
subVersion,
|
})
|
);
|
|
submitFeedback(formData).then((res) => {
|
let { code, data } = res.data;
|
if (code && data) {
|
this.$message.success("反馈成功");
|
this.feedbackShow = false;
|
this.$layer.close(loading);
|
this.flag = 0;
|
this.page = 1;
|
this.searchData();
|
} else {
|
this.$layer.close(loading);
|
this.$message.error("反馈失败");
|
}
|
});
|
},
|
custom(data) {
|
const { id, parentCode, parentModel, parentName } = this.customProd;
|
const param = {
|
versionTime: data.versionTime,
|
customCode: data.customCode,
|
id,
|
parentCode,
|
parentModel,
|
parentName,
|
};
|
let loading = this.$layer.loading({ shade: true });
|
addProduct(param).then((res) => {
|
const { code, msg } = res.data;
|
if (code) {
|
this.$message.success(msg);
|
this.$layer.close(loading);
|
this.customShow = false;
|
} else {
|
this.$message.error(msg);
|
this.$layer.close(loading);
|
}
|
});
|
},
|
customCancel() {
|
this.customShow = false;
|
},
|
activeFN() {
|
this.resize();
|
},
|
uploadBom() {
|
this.file = null;
|
this.fromProd = undefined;
|
this.bomUploadShow = true;
|
},
|
bomUploadCancel() {
|
this.bomUploadShow = false;
|
},
|
bomUploadOk() {
|
if (!this.file) {
|
this.$message.warn("请选择要上传的压缩包");
|
return false;
|
}
|
let loading = this.$layer.loading();
|
const formData = new FormData();
|
formData.append("file", this.file);
|
if (this.fromProd) {
|
const prod = this.prodList
|
.filter((v) => v.id == this.fromProd)
|
.map((v) => ({
|
parentCode: v.parentCode,
|
customCode: v.customCode,
|
}))[0];
|
formData.append("baseStr", JSON.stringify(prod));
|
}
|
this.$nextTick(() => {
|
zipParse(formData)
|
.then((res) => {
|
this.$layer.close(loading);
|
let { code, data, data2, data3, msg } = res.data;
|
if (code && data) {
|
this.resList = data2;
|
let abAndErr = this.getAbAndError(data2.bomList);
|
this.abTbl.dataSource = abAndErr.ab;
|
this.errorTbl.dataSource = abAndErr.error;
|
|
this.diffData = {
|
addList: data3.addList,
|
delList: data3.deleteList.map((v) => v.materialObj),
|
updateList: data3.diffList,
|
};
|
this.fileUrl = msg;
|
this.prodUploadShow = true;
|
this.$message.success("解析成功");
|
} else {
|
if (msg == "名称或型号命名不规范") {
|
this.errorTbl2.dataSource = data2;
|
this.errorVisible = true;
|
} else {
|
this.$message.error(msg);
|
}
|
}
|
})
|
.catch((error) => {
|
this.$layer.close(loading);
|
console.log(error);
|
});
|
});
|
this.bomUploadShow = false;
|
},
|
/**
|
* 获取异常和错误的Bom信息
|
* @param list
|
* @returns {{ab: *[], error: *[]}}
|
*/
|
getAbAndError(list) {
|
let ab = ["0101", "0102", "0103", "0105", "0106"];
|
let error = ["0104"];
|
let result = {
|
ab: [],
|
error: [],
|
};
|
for (let i = 0; i < list.length; i++) {
|
let item = list[i];
|
let subCode = item.subCode.trim().slice(0, 4);
|
let dwgExist = item.dwgExist;
|
if (!dwgExist) {
|
let isInAb = false;
|
for (let j = 0; j < ab.length; j++) {
|
if (ab[j] == subCode) {
|
result.ab.push(item);
|
isInAb = true;
|
break;
|
}
|
}
|
// 是否已经存在ab中
|
if (!isInAb) {
|
for (let j = 0; j < error.length; j++) {
|
if (error[j] == subCode) {
|
result.error.push(item);
|
break;
|
}
|
}
|
}
|
}
|
}
|
return result;
|
},
|
getAllProducts() {
|
getAllProducts().then((res) => {
|
let { code, data, data2, msg } = res.data;
|
let list = [];
|
if (code && data) {
|
list = data2;
|
}
|
this.prodList = list;
|
});
|
},
|
prodFilter(str, option) {
|
const txt = option.componentOptions.children[0].text;
|
str = str.trim();
|
const reg = new RegExp(str, "ig");
|
return reg.test(txt);
|
},
|
viewLog(obj) {
|
// console.log(obj);
|
const { parentCode, customCode } = obj;
|
getLogList({ parentCode, customCode }).then((res) => {
|
const { code, data } = res.data;
|
if (code) {
|
this.logList = data;
|
this.logVisible = true;
|
} else {
|
this.$message.error("日志查询失败");
|
}
|
});
|
},
|
logCancel() {
|
this.logVisible = false;
|
},
|
prodDiff() {
|
this.$router.push("/resource/product-diff");
|
},
|
showEcrlist(record) {
|
this.ecrList = record.ecrList;
|
this.ecrListVisible = true;
|
},
|
ecrListCancel() {
|
this.ecrListVisible = false;
|
},
|
getRoleUser() {
|
getRoleUser(1)
|
.then((res) => {
|
let { code, data, data2 } = res.data;
|
let list = [];
|
if (code && data) {
|
// console.log(data);
|
list = data2.map((v) => v.name);
|
}
|
this.tester = list;
|
})
|
.catch((err) => {
|
console.log(err);
|
});
|
},
|
downloadLog(record) {
|
// console.log(record);
|
let { customCode, parentCode } = record;
|
this.oprateInfo = parentCode + "_" + customCode;
|
this.downloadlogVisible = true;
|
},
|
ownerDownloadLog() {
|
this.ownerLogVisible = true;
|
},
|
ownerLogClose() {
|
this.ownerLogVisible = false;
|
},
|
},
|
watch: {
|
update(n) {
|
if (-1 != n && !this._inactive) {
|
this.$nextTick(() => {
|
const table = this.$refs.table;
|
const header = document.querySelectorAll(
|
".doc-center-table .ant-table-header"
|
)[0].clientHeight;
|
const bar = document.querySelectorAll(".header-bar")[0].clientHeight;
|
if (table.fullScreen) {
|
this.y = table.$el.clientHeight - bar - header - 64;
|
} else {
|
const wraper = this.$refs.wraper.clientHeight;
|
const card = document.querySelectorAll(".ant-card-body")[0];
|
const { paddingBottom, paddingTop } = getComputedStyle(card, null);
|
const h =
|
wraper -
|
header -
|
64 -
|
bar -
|
parseInt(paddingBottom) -
|
parseInt(paddingTop);
|
// console.log(h, "h",wraper, header, bar );
|
this.y = h;
|
}
|
});
|
}
|
},
|
affixed() {
|
setTimeout(() => {
|
this.update = Math.random();
|
}, 200);
|
},
|
prodUploadShow(n) {
|
// 关闭弹出框清空数据并不能忽视异常数据
|
if (!n) {
|
this.errorTbl.dataSource = [];
|
this.abTbl.dataSource = [];
|
this.abTbl.ignore = false;
|
}
|
},
|
},
|
computed: {
|
...mapGetters("account", [
|
"roles",
|
"projectManagerList",
|
"generalManagerList",
|
"permits",
|
"user",
|
]),
|
...mapGetters("setting", ["affixed"]),
|
canUploadBom() {
|
return checkPermit(PERMITS.uploadBom, this.permits);
|
},
|
// canUploadSoftware() {
|
// return checkPermit(PERMITS.uploadSoftware, this.permits);
|
// },
|
canDownloadBom() {
|
return checkPermit(PERMITS.downloadBom, this.permits);
|
},
|
canFeedback() {
|
return checkPermit(PERMITS.feedback, this.permits);
|
},
|
abLabel() {
|
let num = this.abTbl.dataSource.length;
|
num = num > 99 ? "99+" : num;
|
return "异常(" + num + ")";
|
},
|
errorLabel() {
|
let num = this.errorTbl.dataSource.length;
|
num = num > 99 ? "99+" : num;
|
return "错误(" + num + ")";
|
},
|
abState() {
|
let result = false;
|
if (this.abTbl.dataSource.length != 0) {
|
if (this.abTbl.ignore) {
|
result = false;
|
} else {
|
result = true;
|
}
|
} else {
|
result = false;
|
}
|
|
return result;
|
},
|
submitState() {
|
let result = {
|
code: 0,
|
msg: "存在异常或错误的数据,请修复后再提交",
|
};
|
if (this.abState) {
|
result.code = 1;
|
} else {
|
result.code = 0;
|
}
|
|
if (this.errorTbl.dataSource.length != 0) {
|
result.code = 1;
|
}
|
|
return result;
|
},
|
isTester() {
|
return this.tester.some((v) => v == this.user.name);
|
},
|
},
|
mounted() {
|
this.searchAllUserList();
|
this.getRoleUser();
|
this.getUserByRoleId();
|
this.sendMessage();
|
this.getAllProducts();
|
window.addEventListener("resize", this.resize);
|
},
|
destroyed() {
|
window.removeEventListener("resize", this.resize);
|
},
|
};
|
</script>
|
|
<style scoped lang="less">
|
.main {
|
height: 100%;
|
position: relative;
|
|
.inner {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
}
|
}
|
|
.img-wraper {
|
width: 80px;
|
height: 50px;
|
display: inline-block;
|
|
.image-view {
|
width: 100%;
|
height: 100%;
|
|
/deep/img {
|
width: 100%;
|
height: 100%;
|
object-fit: contain;
|
}
|
}
|
}
|
|
/deep/table {
|
table-layout: fixed;
|
}
|
|
.text-right {
|
text-align: right;
|
|
span::after {
|
content: ":";
|
position: relative;
|
top: -0.5px;
|
margin: 0 8px 0 2px;
|
}
|
}
|
|
.upload {
|
padding: 10px 0;
|
}
|
|
.modal-footer {
|
text-align: right;
|
|
button + button {
|
margin-left: 8px;
|
}
|
}
|
|
.mt8 {
|
margin-top: 8px;
|
}
|
|
.from {
|
width: 100%;
|
}
|
|
.label {
|
display: flex;
|
justify-content: flex-end;
|
padding-right: 1em;
|
align-items: center;
|
}
|
|
.bom-list /deep/ .ant-card-body {
|
padding: 8px 24px;
|
}
|
|
.log-content {
|
max-height: 400px;
|
overflow-y: auto;
|
|
.user {
|
color: #23aaf2;
|
font-weight: 700;
|
}
|
|
.time {
|
color: #f9be13;
|
font-weight: 700;
|
}
|
|
.version {
|
color: #0aedb2;
|
font-weight: 700;
|
}
|
|
.ant-timeline-item:first-of-type {
|
padding-top: 6px;
|
}
|
}
|
|
.table-title {
|
font-weight: 700;
|
color: #13c2c2;
|
}
|
|
.btn-grp .ant-btn {
|
min-width: 6.4em;
|
}
|
/deep/.locked > td {
|
background: #fec54b;
|
}
|
/deep/.locked.locked.locked.ant-table-row-hover > td,
|
/deep/.locked.locked.locked:hover > td {
|
background: #fcd583;
|
}
|
/deep/.unable > td {
|
background: #f0637b;
|
}
|
/deep/.unable.unable.unable.ant-table-row-hover > td,
|
/deep/.unable.unable.unable:hover > td {
|
background: #ff869a;
|
}
|
</style>
|
|
<style lang="less">
|
.full-modal {
|
height: 100%;
|
.ant-modal {
|
max-width: 100%;
|
height: 100%;
|
top: 0;
|
padding-bottom: 0;
|
margin: 0;
|
}
|
.ant-modal-content {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
overflow: hidden;
|
// height: calc(100vh);
|
}
|
.ant-modal-body {
|
flex: 1;
|
}
|
}
|
</style>
|