| | |
| | | |
| | | uploadBom: 10009, |
| | | uploadSoftware: 10008, |
| | | lockBom: 10010 |
| | | lockBom: 10010, |
| | | lockOther: 10011 |
| | | } |
| | |
| | | import AKeepAlive from '@/components/cache/AKeepAlive' |
| | | import TabsHead from '@/layouts/tabs/TabsHead' |
| | | |
| | | import createWs from "@/assets/js/websocket"; |
| | | const WSMixin = createWs("loginCheck"); |
| | | |
| | | export default { |
| | | name: 'TabsView', |
| | | i18n: require('./i18n'), |
| | | mixins: [WSMixin], |
| | | components: {TabsHead, PageToggleTransition, Contextmenu, AdminLayout , AKeepAlive }, |
| | | data () { |
| | | return { |
| | |
| | | } |
| | | }) |
| | | }, |
| | | onWSMessage(res) { |
| | | res = JSON.parse(res.data); |
| | | console.log(res, "loginCheck"); |
| | | // this.searchData(res); |
| | | if (!res.data.checkLogin.data) { |
| | | this.$layer.msg(res.data.checkLogin.msg); |
| | | //this.WSClose2(); |
| | | setTimeout(() => { |
| | | this.$router.push("/login"); |
| | | location.reload(); |
| | | }, 2000); |
| | | } |
| | | }, |
| | | ...mapMutations('setting', ['correctPageMinHeight']) |
| | | } |
| | | } |
| | |
| | | <template> |
| | | <div class="" :style="{ width: width + 'px' }"> |
| | | <div class=""> |
| | | <a-table |
| | | ref="aTable" |
| | | size="small" |
| | |
| | | :data-source="dataSource" |
| | | :pagination="false" |
| | | :rowKey="(record, index) => index" |
| | | :rowClassName="(record) => (1 == record.lockFlag ? 'is-lock' : '')" |
| | | > |
| | | <template slot="action" slot-scope="text, record"> |
| | | <div v-if="record.url"> |
| | | <a @click="view(record)">预览</a> |
| | | <template v-if="canDownloadOther"> |
| | | <a v-if="!record.lockFlag" @click="view(record)">预览</a> |
| | | <template v-if="canDownloadOther && !record.lockFlag"> |
| | | <a-divider type="vertical"></a-divider> |
| | | <a @click="downloadLog(record)">下载</a> |
| | | </template> |
| | | <template v-if="canLockOther"> |
| | | <a-divider v-if="!record.lockFlag" type="vertical"></a-divider> |
| | | <a @click="lock(record)">{{ record.lockFlag ? "解锁" : "锁定" }}</a> |
| | | </template> |
| | | </div> |
| | | </template> |
| | |
| | | > |
| | | <img alt="example" style="width: 100%" :src="imgUrl" /> |
| | | </a-modal> |
| | | <a-modal |
| | | :width="400" |
| | | :visible="reasonVisible" |
| | | 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> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import getWebUrl from "@/assets/js/tools/getWebUrl"; |
| | | import { dwgReview } from "@/pages/workplace/apis"; |
| | | import { downloadLog } from "@/pages/system/logs/apis"; |
| | | import { updateAttachLock } from "@/pages/resourceManage/materialsCenter/apis"; |
| | | import checkPermit from "@/assets/js/tools/checkPermit"; |
| | | import PERMITS from "@/assets/js/const/const_permits"; |
| | | import { mapGetters } from "vuex"; |
| | |
| | | return []; |
| | | }, |
| | | }, |
| | | width: { |
| | | type: Number, |
| | | default: 600, |
| | | info: { |
| | | type: Object, |
| | | default() { |
| | | return null; |
| | | }, |
| | | }, |
| | | }, |
| | | data() { |
| | |
| | | width: 100, |
| | | }, |
| | | { |
| | | title: "操作原因", |
| | | dataIndex: "localReason", |
| | | align: "center", |
| | | }, |
| | | { |
| | | title: "操作", |
| | | dataIndex: "operation", |
| | | key: "operation", |
| | | align: "center", |
| | | width: 100, |
| | | width: 140, |
| | | scopedSlots: { customRender: "action" }, |
| | | }, |
| | | ]; |
| | | return { |
| | | reason: "", |
| | | reasonVisible: false, |
| | | currObj: null, |
| | | columns, |
| | | y: 500, |
| | | imgUrl: "", |
| | |
| | | document.body.removeChild(link); |
| | | downloadLog(parentModel, subModel); |
| | | }, |
| | | lock(obj) { |
| | | this.currObj = obj; |
| | | this.reason = ''; |
| | | this.reasonVisible = true; |
| | | }, |
| | | reasonCancel() { |
| | | this.reasonVisible = false; |
| | | }, |
| | | reasonOk() { |
| | | if (!this.id) { |
| | | this.$message.error("无效的物料ID"); |
| | | return false; |
| | | } |
| | | let obj = this.currObj; |
| | | let lockFlag = !obj.lockFlag * 1; |
| | | let params = { |
| | | attachName: obj.fileName, |
| | | localReason: this.reason, |
| | | lockFlag, |
| | | materialId: this.id, |
| | | }; |
| | | updateAttachLock([params]).then((res) => { |
| | | const { code, data, msg } = res.data; |
| | | if (code && data) { |
| | | this.$message.success(msg); |
| | | obj.lockFlag = lockFlag; |
| | | obj.localReason = this.reason; |
| | | this.reasonVisible = false; |
| | | } else { |
| | | this.$message.error(msg); |
| | | } |
| | | }); |
| | | }, |
| | | }, |
| | | computed: { |
| | | dataSource() { |
| | | let attachLocks = this.attachLocks; |
| | | let reg = /(.*\\+)*(.*)$/; |
| | | return this.list.map((item) => { |
| | | let fileName = item.match(reg)[2]; |
| | | let arr = fileName.split("."); |
| | | let fileType = arr.length ? arr[arr.length - 1].toLowerCase() : ""; |
| | | let localReason = ""; |
| | | let lockFlag = 0; |
| | | attachLocks.forEach((v) => { |
| | | if (v.attachName == fileName) { |
| | | localReason = v.localReason; |
| | | lockFlag = v.lockFlag; |
| | | } |
| | | }); |
| | | return { |
| | | fileName, |
| | | fileType, |
| | | url: item, |
| | | localReason, |
| | | lockFlag, |
| | | }; |
| | | }); |
| | | }, |
| | | id() { |
| | | return this.info ? this.info.id : 0; |
| | | }, |
| | | attachLocks() { |
| | | return this.info ? this.info.attachLocks : []; |
| | | }, |
| | | ...mapGetters("account", ["permits"]), |
| | | canDownloadOther() { |
| | | return checkPermit(PERMITS.canDownloadOther, this.permits); |
| | | return checkPermit(PERMITS.downloadOther, this.permits); |
| | | }, |
| | | canLockOther() { |
| | | return checkPermit(PERMITS.lockOther, this.permits); |
| | | }, |
| | | }, |
| | | mounted() {}, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style lang="less" scoped> |
| | | /deep/.is-lock td { |
| | | background: #ddd; |
| | | } |
| | | </style> |
| | |
| | | } |
| | | |
| | | /** |
| | | * 根据物料id查询物料信息 |
| | | * |
| | | * @returns |
| | | */ |
| | | export const uploadOthers = (data) => { |
| | |
| | | }, |
| | | data |
| | | }) |
| | | } |
| | | /** |
| | | * 修改附件锁定状态 |
| | | * @returns |
| | | */ |
| | | export const updateAttachLock = (data) => { |
| | | return axios({ |
| | | method: "POST", |
| | | url: "attachLock/updateAttachLock", |
| | | data |
| | | }) |
| | | } |
| | |
| | | title="附件" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | :width="650" |
| | | :width="850" |
| | | :footer="null" |
| | | @cancel="fileListCancel" |
| | | > |
| | | <files-table :list="fileList"></files-table> |
| | | <files-table :list="fileList" :info="info"></files-table> |
| | | <div class="footer"> |
| | | <a-space> |
| | | <a-button @click="fileListCancel">关闭</a-button> |
| | |
| | | v-if="canUpload" |
| | | :before-upload="beforeUpload" |
| | | @change="fileUploadChange" |
| | | :showUploadList="false" |
| | | multiple |
| | | accept=".zip" |
| | | > |
| | | <!-- :showUploadList="false" --> |
| | | <a-button type="primary">上传附件</a-button> |
| | | </a-upload> |
| | | </a-space> |
| | |
| | | import { dwgReview } from "@/pages/workplace/apis"; |
| | | import { downloadLog } from "@/pages/system/logs/apis"; |
| | | import { mapGetters } from "vuex"; |
| | | import checkPermit from '@/assets/js/tools/checkPermit'; |
| | | import PERMITS from '@/assets/js/const/const_permits'; |
| | | import checkPermit from "@/assets/js/tools/checkPermit"; |
| | | import PERMITS from "@/assets/js/const/const_permits"; |
| | | |
| | | import createWs from "@/assets/js/websocket"; |
| | | const WSMixin = createWs("material"); |
| | |
| | | mixins: [WSMixin], |
| | | data() { |
| | | return { |
| | | info: {}, |
| | | fileListShow: false, |
| | | fileList: [], |
| | | resShow: false, |
| | |
| | | return this.isAdd ? "批量增加关联关系" : "批量解除关联关系"; |
| | | }, |
| | | ...mapGetters("setting", ["affixed"]), |
| | | ...mapGetters('account', ['permits']), |
| | | ...mapGetters("account", ["permits"]), |
| | | canUpload() { |
| | | return checkPermit(PERMITS.uploadBom, this.permits); |
| | | }, |
| | |
| | | pageCurr, |
| | | ...params, |
| | | }; |
| | | console.log("=====9=", data, JSON.stringify(data)); |
| | | // console.log("=====9=", data, JSON.stringify(data)); |
| | | this.SOCKET.send(JSON.stringify(data)); |
| | | }, |
| | | onWSMessage(res) { |
| | |
| | | subCode, |
| | | subModel, |
| | | }; |
| | | formData.append("multipartFile", data.file); |
| | | |
| | | formData.append("materialStr", JSON.stringify(obj)); |
| | | data.fileList.forEach((v, i) => { |
| | | formData.append("file", v.originFileObj); |
| | | }); |
| | | uploadOthers(formData) |
| | | .then((res) => { |
| | | this.$layer.close(loading); |
| | |
| | | this.resize(); |
| | | }, |
| | | panelShow(obj) { |
| | | const { id, dwgUrl } = obj; |
| | | const { id, dwgUrl, attachLocks } = obj; |
| | | this.currentObj = obj; |
| | | getFileList(id).then((res) => { |
| | | const { code, data, data2 } = res.data; |
| | |
| | | if (code && data) { |
| | | list = data2; |
| | | } |
| | | this.fileList = list; |
| | | if (dwgUrl) { |
| | | this.fileList.unshift(dwgUrl); |
| | | list.unshift(dwgUrl); |
| | | } |
| | | this.info = { attachLocks, id }; |
| | | this.fileList = list; |
| | | this.fileListShow = true; |
| | | }); |
| | | }, |
| | |
| | | url: "product/setpHistoryEnable", |
| | | params |
| | | }) |
| | | } |
| | | /** |
| | | * 产品操作日志查询 |
| | | * customCode=1&parentCode=1 |
| | | * @returns |
| | | */ |
| | | export const getLogList = (params) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "productLockLog/listByParentCodeAndCustomCode", |
| | | params |
| | | }) |
| | | } |
| | |
| | | > |
| | | <diff-list :list="diffData"></diff-list> |
| | | </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> |
| | | </a-layout> |
| | | </template> |
| | | |
| | |
| | | mixins: [WSMixin], |
| | | data() { |
| | | return { |
| | | reasonVisible: false, |
| | | reason: '', |
| | | lastId: undefined, |
| | | diffShow: false, |
| | | diffData: [], |
| | |
| | | this.diffShow = false; |
| | | }, |
| | | changeStatus() { |
| | | this.reasonVisible = true; |
| | | }, |
| | | reasonCancel() { |
| | | this.reasonVisible = false; |
| | | }, |
| | | reasonOk() { |
| | | let { |
| | | currentVersion: { customCode, parentCode, enabled, version }, |
| | | currentVersion: { customCode, parentCode, enabled, version, versionTime }, |
| | | reason |
| | | } = this; |
| | | enabled = !enabled * 1; |
| | | setpHistoryEnable({ customCode, parentCode, enabled, version }).then( |
| | | setpHistoryEnable({ customCode, parentCode, enabled, version, reason, versionTime }).then( |
| | | (res) => { |
| | | let { code, data } = res.data; |
| | | if (code && data) { |
| | | this.$message.success("操作成功"); |
| | | this.currentVersion.enabled = enabled; |
| | | this.reasonVisible = false; |
| | | } else { |
| | | this.$message.error("操作失败"); |
| | | } |
| | | } |
| | | ); |
| | | }, |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.sendMessage(); |
| | |
| | | <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 direction="vertical" slot="content"> |
| | | <a-button type="primary" @click="edit(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" |
| | | type="primary" |
| | | @click="download(record)" |
| | | >下载</a-button |
| | |
| | | <a-button |
| | | type="primary" |
| | | v-if="canUploadBom" |
| | | :disabled="record.version == -1" |
| | | @click="showCustom(record)" |
| | | >定制</a-button |
| | | > |
| | |
| | | @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'" |
| | | > |
| | | <p> |
| | | <span class="user">{{ item.owner }}</span |
| | | > 在 <span class="time">{{ item.createTime }}</span |
| | | > {{ item.lockFlag ? "锁定" : "激活" }}了版本 <span class="version">{{ item.versionTime }}</span> |
| | | </p> |
| | | <p>操作原因: {{ item.reason ? item.reason : "无" }}</p> |
| | | </a-timeline-item> |
| | | </a-timeline> |
| | | <a-empty v-else /> |
| | | </div> |
| | | </a-modal> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import DrawUpload from "@/pages/components/drawUpload"; |
| | | |
| | | import getWebUrl from "@/assets/js/tools/getWebUrl"; |
| | | import { addProduct, downloadBom, getAllProducts } from "./apis"; |
| | | import { addProduct, downloadBom, getAllProducts, getLogList } from "./apis"; |
| | | import { productSoftwareSubmit } from "../software/apis"; |
| | | import { zipParse } from "@/pages/workplace/myDraw/apis"; |
| | | import { mapGetters } from "vuex"; |
| | |
| | | mixins: [WSMixin], |
| | | data() { |
| | | return { |
| | | logVisible: false, |
| | | logList: [], |
| | | fromProd: undefined, |
| | | prodList: [], |
| | | diffData: {}, |
| | |
| | | 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; |
| | | }, |
| | | }, |
| | | watch: { |
| | | update(n) { |
| | |
| | | .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; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | data |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @returns |
| | | */ |
| | | export const applyModel = (data) => { |
| | | return axios({ |
| | | method: "PUT", |
| | | url: "software/applyModel", |
| | | data |
| | | }) |
| | | } |
| | |
| | | <td colspan="3">{{ summarize.fileName }}</td> |
| | | </tr> |
| | | <tr> |
| | | <th>板号</th> |
| | | <td colspan="3">{{ summarize.boardNumber }}</td> |
| | | </tr> |
| | | <tr> |
| | | <th>软件类型</th> |
| | | <td colspan="3">{{ summarize.type }}</td> |
| | | </tr> |
| | |
| | | <a-divider type="vertical"></a-divider> |
| | | <a @click="download(record)">下载</a> |
| | | </template> |
| | | <template v-if="canUploadSoftware"> |
| | | <a-divider type="vertical"></a-divider> |
| | | <a @click="updateDesc(record)">更新说明</a> |
| | | </template> |
| | | </template> |
| | | </advance-table> |
| | | </a-card> |
| | |
| | | @cancel="uploadCancel" |
| | | > |
| | | <div class=""> |
| | | <a-row type="flex" class="row"> |
| | | <a-row v-if="!onlyXls" type="flex" class="row"> |
| | | <a-col flex="6em" class="label">软件包</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | |
| | | </div> |
| | | <div class="modal-footer"> |
| | | <a-button type="danger" @click="uploadCancel"> 取消 </a-button> |
| | | <a-button type="primary" @click="uploadSoftware"> 提交 </a-button> |
| | | <a-button v-if="!onlyXls" type="primary" @click="uploadSoftware"> 提交 </a-button> |
| | | <a-button v-else type="primary" @click="applyModel"> 提交 </a-button> |
| | | </div> |
| | | </div> |
| | | </a-modal> |
| | |
| | | downLoadSoftware, |
| | | excelParse, |
| | | productSoftwareSubmit, |
| | | applyModel |
| | | } from "./apis"; |
| | | import { mapGetters } from "vuex"; |
| | | |
| | |
| | | name: "", |
| | | data() { |
| | | return { |
| | | onlyXls: false, |
| | | resData: [], |
| | | file: null, |
| | | file1: null, |
| | |
| | | dataIndex: "soft.owner", |
| | | align: "center", |
| | | searchAble: true, |
| | | width: 160 |
| | | width: 160, |
| | | }, |
| | | { |
| | | title: "适用机型号", |
| | |
| | | title: "操作", |
| | | dataIndex: "operation", |
| | | align: "center", |
| | | width: 168, |
| | | width: 228, |
| | | fixed: "right", |
| | | scopedSlots: { customRender: "action" }, |
| | | noSearch: true, |
| | |
| | | width: 180, |
| | | noSearch: true, |
| | | }, |
| | | ] |
| | | ], |
| | | }; |
| | | }, |
| | | components: { |
| | |
| | | Object.keys(conditions).forEach((v) => { |
| | | switch (v) { |
| | | case "soft.fileName": |
| | | params[v] = conditions['fileName']; |
| | | params[v] = conditions["fileName"]; |
| | | break; |
| | | case "soft.owner": |
| | | params[v] = conditions['owner']; |
| | | params[v] = conditions["owner"]; |
| | | break; |
| | | default: |
| | | params[v] = conditions[v]; |
| | |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resData = []; |
| | | this.onlyXls = false; |
| | | this.uploadShow = true; |
| | | }, |
| | | updateDesc() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resData = []; |
| | | this.onlyXls = true; |
| | | this.uploadShow = true; |
| | | }, |
| | | beforeUpload() { |
| | |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | applyModel() { |
| | | if (!this.file1) { |
| | | this.$message.error("请选择软件说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resData.length) { |
| | | this.$message.error("软件说明文件解析异常"); |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file1); |
| | | formData.append("softwareStr", JSON.stringify(this.resData)); |
| | | applyModel(formData) |
| | | .then((res) => { |
| | | let { code, data, msg } = res.data; |
| | | if (code) { |
| | | this.uploadShow = false; |
| | | this.$message.success(msg); |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error(msg); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | }, |
| | | watch: { |
| | | update(n) { |