| | |
| | | <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" |
| | | title=" " |
| | | :row-key="(record, index) => index" |
| | | @search="onSearch" |
| | | @refresh="onRefresh" |
| | | @reset="onReset" |
| | | :format-conditions="true" |
| | | :scroll="{ y }" |
| | | :pagination="{ |
| | | <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" |
| | | title=" " |
| | | :row-key="(record, index) => index" |
| | | @search="onSearch" |
| | | @refresh="onRefresh" |
| | | @reset="onReset" |
| | | :format-conditions="true" |
| | | :scroll="{ y }" |
| | | :pagination="{ |
| | | current: pageCurr, |
| | | pageSize: pageSize, |
| | | total: total, |
| | |
| | | `第 ${range[0]}-${range[1]} 条,总计 ${total} 条`, |
| | | onChange: onPageChange, |
| | | onShowSizeChange: onSizeChange, |
| | | }"> |
| | | <template slot="action" slot-scope="{ record }"> |
| | | <a-popover v-if="!record.currentFlag" title="" trigger="hover"> |
| | | <div class="" slot="content" style="width: 450px"> |
| | | <a-table |
| | | size="small" |
| | | :scroll="{ y: 300 }" |
| | | bordered |
| | | :columns="prodsColumns" |
| | | :data-source="record.sopProductList" |
| | | :pagination="false" |
| | | :expandRowByClick="true" |
| | | :row-key="(record1, index) => index" |
| | | > |
| | | <!-- <template slot="action" slot-scope="record1"> |
| | | }" |
| | | > |
| | | <template slot="action" slot-scope="{ record }"> |
| | | <a-popover v-if="!record.currentFlag" title="" trigger="hover"> |
| | | <div class="" slot="content" style="width: 450px"> |
| | | <a-table |
| | | size="small" |
| | | :scroll="{ y: 300 }" |
| | | bordered |
| | | :columns="prodsColumns" |
| | | :data-source="record.sopProductList" |
| | | :pagination="false" |
| | | :expandRowByClick="true" |
| | | :row-key="(record1, index) => index" |
| | | > |
| | | <!-- <template slot="action" slot-scope="record1"> |
| | | 123{{ record1 }} |
| | | </template> --> |
| | | </a-table> |
| | | </div> |
| | | <a>适用产品</a> |
| | | </a-popover> |
| | | <a-tag v-else class="tag-all" color="#f50"> 适用全部 </a-tag> |
| | | <template v-if="canDownload"> |
| | | <a-divider type="vertical"></a-divider> |
| | | <a v-if="record.isCanPreview" :disabled="!record.status" @click="downloadFile(record)">预览</a> |
| | | <a v-else :disabled="!record.status" @click="downloadFile(record)">下载</a> |
| | | </template> |
| | | </template> |
| | | </advance-table> |
| | | </a-card> |
| | | </a-spin> |
| | | </div> |
| | | <pop |
| | | :visible.sync="popVisible" |
| | | :x="popPosition.x" |
| | | :y="popPosition.y" |
| | | :position="popPosition.dir" |
| | | :info="popInfo" |
| | | ></pop> |
| | | <a-modal |
| | | :visible="uploadShow" |
| | | :footer="null" |
| | | :width="800" |
| | | title="上传SOP" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | @cancel="uploadCancel" |
| | | > |
| | | <div class=""> |
| | | <template v-if="!onlyXls"> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">sop文件</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | | class="upload" |
| | | :before-upload="beforeUpload" |
| | | @change="uploadChange" |
| | | accept=".zip,.rar" |
| | | > |
| | | <a-button type="primary">选文件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | | </a-row> |
| | | </template> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">SOP说明</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | | class="upload" |
| | | :before-upload="beforeUpload" |
| | | @change="uploadChange1" |
| | | accept=".xls,.xlsx" |
| | | > |
| | | <a-button type="primary">说明文件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | | </a-row> |
| | | <div class="sub-title">说明文件解析结果</div> |
| | | <div class="res-content"> |
| | | <desc-res :info="resObj"></desc-res> |
| | | </div> |
| | | <div class="modal-footer"> |
| | | <a-button type="danger" @click="uploadCancel"> 取消 </a-button> |
| | | <a-button v-if="!onlyXls" type="primary" @click="uploadSop"> |
| | | 提交 |
| | | </a-button> |
| | | <a-button v-else type="primary" @click="applyModel"> 提交 </a-button> |
| | | </div> |
| | | </div> |
| | | </a-modal> |
| | | <a-modal |
| | | :visible="emailShow" |
| | | :footer="null" |
| | | :width="760" |
| | | title="邮件发送" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | @cancel="emailCancel" |
| | | > |
| | | <email-card |
| | | :visible.sync="emailShow" |
| | | :users="userList" |
| | | :title="emailInfo.title" |
| | | :content="emailInfo.content" |
| | | :type="2" |
| | | v-if="emailShow" |
| | | ></email-card> |
| | | </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-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.status == 0 ? 'red' : 'green'" |
| | | > |
| | | <div> |
| | | <span class="user">{{ item.userName }}</span> 在 |
| | | <span class="time">{{ item.createTime }}</span> |
| | | {{ item.status == 0 ? "锁定" : "解锁" }}了版本 |
| | | <span class="version">{{ item.fileVersion }}</span> |
| | | </div> |
| | | <div>操作原因: {{ item.reason ? item.reason : "无" }}</div> |
| | | </a-timeline-item> |
| | | </a-timeline> |
| | | <a-empty v-else /> |
| | | </div> |
| | | </a-modal> |
| | | </a-table> |
| | | </div> |
| | | <a>适用产品</a> |
| | | </a-popover> |
| | | <a-tag v-else class="tag-all" color="#f50"> 适用全部 </a-tag> |
| | | <template v-if="canDownload"> |
| | | <a-divider type="vertical"></a-divider> |
| | | <a |
| | | v-if="record.isCanPreview" |
| | | :disabled="!record.status" |
| | | @click="downloadFile(record)" |
| | | >预览</a |
| | | > |
| | | <a |
| | | v-else |
| | | :disabled="!record.status" |
| | | @click="downloadFile(record)" |
| | | >下载</a |
| | | > |
| | | </template> |
| | | </template> |
| | | </advance-table> |
| | | </a-card> |
| | | </a-spin> |
| | | </div> |
| | | <pop |
| | | :visible.sync="popVisible" |
| | | :x="popPosition.x" |
| | | :y="popPosition.y" |
| | | :position="popPosition.dir" |
| | | :info="popInfo" |
| | | ></pop> |
| | | <a-modal |
| | | :visible="uploadShow" |
| | | :footer="null" |
| | | :width="800" |
| | | title="上传SOP" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | @cancel="uploadCancel" |
| | | > |
| | | <div class=""> |
| | | <template v-if="!onlyXls"> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">sop文件</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | | class="upload" |
| | | :before-upload="beforeUpload" |
| | | @change="uploadChange" |
| | | accept=".zip,.rar" |
| | | > |
| | | <a-button type="primary">选文件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | | </a-row> |
| | | </template> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">SOP说明</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | | class="upload" |
| | | :before-upload="beforeUpload" |
| | | @change="uploadChange1" |
| | | accept=".xls,.xlsx" |
| | | > |
| | | <a-button type="primary">说明文件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | | </a-row> |
| | | <div class="sub-title">说明文件解析结果</div> |
| | | <div class="res-content"> |
| | | <desc-res :info="resObj"></desc-res> |
| | | </div> |
| | | <div class="modal-footer"> |
| | | <a-button type="danger" @click="uploadCancel"> 取消 </a-button> |
| | | <a-button v-if="!onlyXls" type="primary" @click="uploadSop"> |
| | | 提交 |
| | | </a-button> |
| | | <a-button v-else type="primary" @click="applyModel"> 提交 </a-button> |
| | | </div> |
| | | </div> |
| | | </a-modal> |
| | | <a-modal |
| | | :visible="emailShow" |
| | | :footer="null" |
| | | :width="760" |
| | | title="邮件发送" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | @cancel="emailCancel" |
| | | > |
| | | <email-card |
| | | :visible.sync="emailShow" |
| | | :users="userList" |
| | | :title="emailInfo.title" |
| | | :content="emailInfo.content" |
| | | :type="2" |
| | | v-if="emailShow" |
| | | ></email-card> |
| | | </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-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.status == 0 ? 'red' : 'green'" |
| | | > |
| | | <div> |
| | | <span class="user">{{ item.userName }}</span> 在 |
| | | <span class="time">{{ item.createTime }}</span> |
| | | {{ item.status == 0 ? "锁定" : "解锁" }}了版本 |
| | | <span class="version">{{ item.fileVersion }}</span> |
| | | </div> |
| | | <div>操作原因: {{ item.reason ? item.reason : "无" }}</div> |
| | | </a-timeline-item> |
| | | </a-timeline> |
| | | <a-empty v-else /> |
| | | </div> |
| | | </a-modal> |
| | | |
| | | <!-- 日志 --> |
| | | <a-modal |
| | | :visible="pdfInfo.visible" |
| | | :footer="null" |
| | | :width="960" |
| | | title="文件预览" |
| | | :destroyOnClose="true" |
| | | @cancel="pdfCancel"> |
| | | <div style="height:600px; overflow-y: auto"> |
| | | <iframe :src="pdfInfo.src"></iframe> |
| | | </div> |
| | | |
| | | </a-modal> |
| | | </div> |
| | | <!-- 日志 --> |
| | | <a-modal |
| | | :visible="pdfInfo.visible" |
| | | :footer="null" |
| | | :width="960" |
| | | title="文件预览" |
| | | :destroyOnClose="true" |
| | | @cancel="pdfCancel" |
| | | > |
| | | <div style="height:600px; overflow-y: auto"> |
| | | <iframe :src="pdfInfo.src"></iframe> |
| | | </div> |
| | | </a-modal> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | import EmailCard from "../../components/emailCard"; |
| | | import { getUserList } from "../../permission/apis"; |
| | | import { |
| | | fileParse, |
| | | addSop, |
| | | getList, |
| | | getSopType1, |
| | | getSopType2, |
| | | updateSop, |
| | | sopLock, |
| | | getLogList, |
| | | fileParse, |
| | | addSop, |
| | | getList, |
| | | getSopType1, |
| | | getSopType2, |
| | | updateSop, |
| | | sopLock, |
| | | getLogList, |
| | | } from "./apis"; |
| | | import offset from "@/assets/js/tools/offset"; |
| | | import Pop from "./pop"; |
| | |
| | | import getFileTypeAndName from "@/assets/js/tools/getFileTypeAndName"; |
| | | import VuePdf from "vue-pdf"; |
| | | |
| | | |
| | | export default { |
| | | props: { |
| | | parentCode: { |
| | | type: [String, Number], |
| | | default: 0 |
| | | } |
| | | }, |
| | | components: { |
| | | AdvanceTable, |
| | | Pop, |
| | | DescRes, |
| | | EmailCard, |
| | | VuePdf, |
| | | }, |
| | | name: "list", |
| | | data() { |
| | | return { |
| | | pdfInfo: { |
| | | visible: false, |
| | | src: "", |
| | | loadedRatio: 0, |
| | | page: 1, |
| | | numPages: 0, |
| | | rotate: 0, |
| | | }, |
| | | rowFileName: '', |
| | | logList: [], |
| | | logVisible: false, |
| | | currentObj: null, |
| | | reasonVisible: false, |
| | | reason: "", |
| | | emailShow: false, |
| | | emailInfo: { |
| | | title: "", |
| | | content: "", |
| | | }, |
| | | userList: [], |
| | | onlyXls: false, |
| | | uploadShow: false, |
| | | webUrl: getWebUrl(), |
| | | prodsColumns: [ |
| | | { |
| | | title: "物料编码", |
| | | dataIndex: "code", |
| | | align: "center", |
| | | }, |
| | | { |
| | | title: "型/板号", |
| | | dataIndex: "model", |
| | | align: "center", |
| | | width: 180, |
| | | }, |
| | | // { |
| | | // title: "操作", |
| | | // dataIndex: "operation", |
| | | // align: "center", |
| | | // width: 180, |
| | | // scopedSlots: { customRender: "action" }, |
| | | // }, |
| | | ], |
| | | file: null, |
| | | file1: null, |
| | | resObj: {}, |
| | | popInfo: {}, |
| | | popVisible: false, |
| | | popPosition: { |
| | | x: 500, |
| | | y: 100, |
| | | dir: "bottom", |
| | | }, |
| | | spinning: false, |
| | | loading: false, |
| | | pageCurr: 1, |
| | | pageSize: 20, |
| | | total: 0, |
| | | y: 400, |
| | | update: -1, |
| | | conditions: {}, |
| | | columns: [ |
| | | { |
| | | title: "文件名称", |
| | | dataIndex: "fileName", |
| | | align: "center", |
| | | width: 140, |
| | | searchAble: false, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "发布时间", |
| | | dataIndex: "releaseDate", |
| | | align: "center", |
| | | width: 160, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "负责人", |
| | | dataIndex: "editor", |
| | | align: "center", |
| | | width: 90, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "审核人", |
| | | dataIndex: "auditor", |
| | | align: "center", |
| | | width: 90, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "发布说明", |
| | | dataIndex: "releaseNotes", |
| | | align: "center", |
| | | width: 260, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "操作", |
| | | dataIndex: "operation", |
| | | align: "center", |
| | | width: 200, |
| | | fixed: "right", |
| | | scopedSlots: { customRender: "action" }, |
| | | noSearch: true, |
| | | }, |
| | | ], |
| | | dataSource: [], |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapGetters("account", ["permits"]), |
| | | ...mapGetters("setting", ["affixed"]), |
| | | canUpload() { |
| | | return checkPermit(PERMITS.uploadSoftware, this.permits); |
| | | }, |
| | | canDownload() { |
| | | return checkPermit(PERMITS.downloadSop, this.permits); |
| | | }, |
| | | }, |
| | | 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); |
| | | this.y = h; |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | affixed() { |
| | | setTimeout(() => { |
| | | this.update = Math.random(); |
| | | }, 200); |
| | | }, |
| | | }, |
| | | methods: { |
| | | searchAllUserList() { |
| | | getUserList() |
| | | .then((res) => { |
| | | let rs = res.data; |
| | | if (rs.code && rs.data) { |
| | | this.userList = rs.data2; |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | showUpload() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resObj = {}; |
| | | this.onlyXls = false; |
| | | this.uploadShow = true; |
| | | }, |
| | | updateDesc(row) { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resObj = { rowId: row.id }; |
| | | this.rowFileName = row.fileName; |
| | | this.onlyXls = true; |
| | | this.uploadShow = true; |
| | | }, |
| | | uploadCancel() { |
| | | this.uploadShow = false; |
| | | }, |
| | | handleEmailShow(record) { |
| | | this.emailInfo.title = |
| | | "[sop发布记录]" + record.fileName + " 版本号:" + record.fileVersion; |
| | | let sopProductListText = record.sopProductList |
| | | .map((item) => { |
| | | return "物料编码:" + item.code + " 型/板号:" + item.model; |
| | | }) |
| | | .join("\n"); |
| | | this.emailInfo.content = |
| | | "文件基础信息\n" + |
| | | "文件名称:" + |
| | | record.fileName + |
| | | "\n" + |
| | | "文件类型:" + |
| | | record.fileType + |
| | | "\n" + |
| | | "文件版本:" + |
| | | record.fileVersion + |
| | | "\n" + |
| | | "关联版本:" + |
| | | record.fileRelatedVersion + |
| | | "\n" + |
| | | "编制:" + |
| | | record.editor + |
| | | "\n" + |
| | | "审核:" + |
| | | record.auditor + |
| | | "\n" + |
| | | "发布日期:" + |
| | | record.releaseDate + |
| | | "\n" + |
| | | "文件适用产品\n" + |
| | | sopProductListText + |
| | | "\n" + |
| | | "发布说明:" + |
| | | record.releaseNotes; |
| | | this.emailShow = true; |
| | | }, |
| | | emailCancel() { |
| | | this.emailShow = false; |
| | | }, |
| | | uploadSop() { |
| | | if (!this.file) { |
| | | this.$message.error("请选择要上传的压缩包"); |
| | | return false; |
| | | } |
| | | if (!this.file1) { |
| | | this.$message.error("请选择sop说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resObj.fileName) { |
| | | this.$message.error("sop说明文件解析异常"); |
| | | return false; |
| | | } |
| | | // 如果sop文件名称 != sop说明里的文件名称 + 文件版本 则报错拒绝 |
| | | let reg = /(.*)\..{1,5}$/; |
| | | let name1 = this.file.name.match(reg)[1]; |
| | | let { fileName, fileVersion } = this.resObj; |
| | | let name2 = fileName + fileVersion; |
| | | props: { |
| | | parentCode: { |
| | | type: [String, Number], |
| | | default: 0, |
| | | }, |
| | | }, |
| | | components: { |
| | | AdvanceTable, |
| | | Pop, |
| | | DescRes, |
| | | EmailCard, |
| | | VuePdf, |
| | | }, |
| | | name: "list", |
| | | data() { |
| | | return { |
| | | pdfInfo: { |
| | | visible: false, |
| | | src: "", |
| | | loadedRatio: 0, |
| | | page: 1, |
| | | numPages: 0, |
| | | rotate: 0, |
| | | }, |
| | | rowFileName: "", |
| | | logList: [], |
| | | logVisible: false, |
| | | currentObj: null, |
| | | reasonVisible: false, |
| | | reason: "", |
| | | emailShow: false, |
| | | emailInfo: { |
| | | title: "", |
| | | content: "", |
| | | }, |
| | | userList: [], |
| | | onlyXls: false, |
| | | uploadShow: false, |
| | | webUrl: getWebUrl(), |
| | | prodsColumns: [ |
| | | { |
| | | title: "物料编码", |
| | | dataIndex: "code", |
| | | align: "center", |
| | | }, |
| | | { |
| | | title: "型/板号", |
| | | dataIndex: "model", |
| | | align: "center", |
| | | width: 180, |
| | | }, |
| | | // { |
| | | // title: "操作", |
| | | // dataIndex: "operation", |
| | | // align: "center", |
| | | // width: 180, |
| | | // scopedSlots: { customRender: "action" }, |
| | | // }, |
| | | ], |
| | | file: null, |
| | | file1: null, |
| | | resObj: {}, |
| | | popInfo: {}, |
| | | popVisible: false, |
| | | popPosition: { |
| | | x: 500, |
| | | y: 100, |
| | | dir: "bottom", |
| | | }, |
| | | spinning: false, |
| | | loading: false, |
| | | pageCurr: 1, |
| | | pageSize: 20, |
| | | total: 0, |
| | | y: 400, |
| | | update: -1, |
| | | conditions: {}, |
| | | columns: [ |
| | | { |
| | | title: "文件名称", |
| | | dataIndex: "fileName", |
| | | align: "center", |
| | | width: 140, |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "发布时间", |
| | | dataIndex: "releaseDate", |
| | | align: "center", |
| | | width: 160, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "负责人", |
| | | dataIndex: "editor", |
| | | align: "center", |
| | | width: 90, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "审核人", |
| | | dataIndex: "auditor", |
| | | align: "center", |
| | | width: 90, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "发布说明", |
| | | dataIndex: "releaseNotes", |
| | | align: "center", |
| | | width: 260, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "操作", |
| | | dataIndex: "operation", |
| | | align: "center", |
| | | width: 200, |
| | | fixed: "right", |
| | | scopedSlots: { customRender: "action" }, |
| | | noSearch: true, |
| | | }, |
| | | ], |
| | | dataSource: [], |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapGetters("account", ["permits"]), |
| | | ...mapGetters("setting", ["affixed"]), |
| | | canUpload() { |
| | | return checkPermit(PERMITS.uploadSoftware, this.permits); |
| | | }, |
| | | canDownload() { |
| | | return checkPermit(PERMITS.downloadSop, this.permits); |
| | | }, |
| | | }, |
| | | 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); |
| | | this.y = h; |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | affixed() { |
| | | setTimeout(() => { |
| | | this.update = Math.random(); |
| | | }, 200); |
| | | }, |
| | | }, |
| | | methods: { |
| | | searchAllUserList() { |
| | | getUserList() |
| | | .then((res) => { |
| | | let rs = res.data; |
| | | if (rs.code && rs.data) { |
| | | this.userList = rs.data2; |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | showUpload() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resObj = {}; |
| | | this.onlyXls = false; |
| | | this.uploadShow = true; |
| | | }, |
| | | updateDesc(row) { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resObj = { rowId: row.id }; |
| | | this.rowFileName = row.fileName; |
| | | this.onlyXls = true; |
| | | this.uploadShow = true; |
| | | }, |
| | | uploadCancel() { |
| | | this.uploadShow = false; |
| | | }, |
| | | handleEmailShow(record) { |
| | | this.emailInfo.title = |
| | | "[sop发布记录]" + record.fileName + " 版本号:" + record.fileVersion; |
| | | let sopProductListText = record.sopProductList |
| | | .map((item) => { |
| | | return "物料编码:" + item.code + " 型/板号:" + item.model; |
| | | }) |
| | | .join("\n"); |
| | | this.emailInfo.content = |
| | | "文件基础信息\n" + |
| | | "文件名称:" + |
| | | record.fileName + |
| | | "\n" + |
| | | "文件类型:" + |
| | | record.fileType + |
| | | "\n" + |
| | | "文件版本:" + |
| | | record.fileVersion + |
| | | "\n" + |
| | | "关联版本:" + |
| | | record.fileRelatedVersion + |
| | | "\n" + |
| | | "编制:" + |
| | | record.editor + |
| | | "\n" + |
| | | "审核:" + |
| | | record.auditor + |
| | | "\n" + |
| | | "发布日期:" + |
| | | record.releaseDate + |
| | | "\n" + |
| | | "文件适用产品\n" + |
| | | sopProductListText + |
| | | "\n" + |
| | | "发布说明:" + |
| | | record.releaseNotes; |
| | | this.emailShow = true; |
| | | }, |
| | | emailCancel() { |
| | | this.emailShow = false; |
| | | }, |
| | | uploadSop() { |
| | | if (!this.file) { |
| | | this.$message.error("请选择要上传的压缩包"); |
| | | return false; |
| | | } |
| | | if (!this.file1) { |
| | | this.$message.error("请选择sop说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resObj.fileName) { |
| | | this.$message.error("sop说明文件解析异常"); |
| | | return false; |
| | | } |
| | | // 如果sop文件名称 != sop说明里的文件名称 + 文件版本 则报错拒绝 |
| | | let reg = /(.*)\..{1,5}$/; |
| | | let name1 = this.file.name.match(reg)[1]; |
| | | let { fileName, fileVersion } = this.resObj; |
| | | let name2 = fileName + fileVersion; |
| | | |
| | | if (name1.toLowerCase() != name2.toLowerCase()) { |
| | | console.log(name1.toLowerCase()+"&&&&&&"+ name2.toLowerCase()); |
| | | this.$message.error("sop与说明文件可能不匹配"); |
| | | return false; |
| | | } |
| | | if (name1.toLowerCase() != name2.toLowerCase()) { |
| | | console.log(name1.toLowerCase() + "&&&&&&" + name2.toLowerCase()); |
| | | this.$message.error("sop与说明文件可能不匹配"); |
| | | return false; |
| | | } |
| | | |
| | | let loading = this.$layer.loading(); |
| | | let loading = this.$layer.loading(); |
| | | |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file); |
| | | // formData.append("file2", this.file1); |
| | | formData.append("sopStr", JSON.stringify(this.resObj)); |
| | | addSop(formData) |
| | | .then((res) => { |
| | | let { code, data, msg } = res.data; |
| | | if (code) { |
| | | this.uploadShow = false; |
| | | this.$message.success("上传成功"); |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error(msg); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | applyModel() { |
| | | if (!this.file1) { |
| | | this.$message.error("请选择sop说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resObj.fileName) { |
| | | this.$message.error("sop说明文件解析异常"); |
| | | return false; |
| | | } |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file); |
| | | // formData.append("file2", this.file1); |
| | | formData.append("sopStr", JSON.stringify(this.resObj)); |
| | | addSop(formData) |
| | | .then((res) => { |
| | | let { code, data, msg } = res.data; |
| | | if (code) { |
| | | this.uploadShow = false; |
| | | this.$message.success("上传成功"); |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error(msg); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | applyModel() { |
| | | if (!this.file1) { |
| | | this.$message.error("请选择sop说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resObj.fileName) { |
| | | this.$message.error("sop说明文件解析异常"); |
| | | return false; |
| | | } |
| | | |
| | | if (this.rowFileName.toLowerCase() != this.resObj.fileName.toLowerCase()) { |
| | | this.$message.error("说明文件与该条记录可能不匹配"); |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | updateSop(this.resObj) |
| | | .then((res) => { |
| | | let { code, data, msg } = res.data; |
| | | if (code) { |
| | | this.uploadShow = false; |
| | | this.$message.success("上传成功"); |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error("解析失败"); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | getSopType1() { |
| | | getSopType1() |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | let list = []; |
| | | if (code) { |
| | | list = data.map((v) => ({ |
| | | title: v.type1, |
| | | value: v.type1, |
| | | })); |
| | | } |
| | | this.columns[0].search.selectOptions = list; |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | }); |
| | | }, |
| | | getSopType2(type) { |
| | | if (type) { |
| | | getSopType2(type) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | let list = []; |
| | | if (code) { |
| | | list = data.map((v) => ({ |
| | | title: v.type2, |
| | | value: v.type2, |
| | | })); |
| | | } |
| | | this.columns[1].search.selectOptions = list; |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | }); |
| | | } else { |
| | | this.columns[1].search.selectOptions = []; |
| | | } |
| | | }, |
| | | cellMouseenter(e, obj) { |
| | | // console.log("enter", e, obj); |
| | | const wraper = this.$refs.wraper; |
| | | const { clientHeight, clientWidth } = wraper; |
| | | const { target, clientX, clientY } = e; |
| | | let { left: x, top: y } = offset(wraper); |
| | | x = clientX - x; |
| | | y = clientY - y; |
| | | // 如果clientHeight 小于380 * 2 则左右布局 |
| | | let dir = "bottom"; |
| | | if (clientHeight < 380 * 2) { |
| | | if (x + 420 + 18 > clientWidth) { |
| | | dir = "left"; |
| | | } else { |
| | | dir = "right"; |
| | | } |
| | | if (y < 180) { |
| | | y = 180; |
| | | } else if (y > clientHeight - 378) { |
| | | y = clientHeight / 2; |
| | | } |
| | | } else { |
| | | if (y + 18 + 360 > clientHeight) { |
| | | // y = clientHeight - 378; |
| | | dir = "top"; |
| | | } else { |
| | | dir = "bottom"; |
| | | } |
| | | if (x < 400) { |
| | | x = 400; |
| | | } |
| | | if (x + 400 > clientWidth) { |
| | | x = clientWidth - 400; |
| | | } |
| | | } |
| | | this.popPosition.x = x; |
| | | this.popPosition.y = y; |
| | | this.popPosition.dir = dir; |
| | | this.popInfo = obj; |
| | | this.popVisible = true; |
| | | }, |
| | | cellMouseleave(e, obj) { |
| | | // console.log("leave", obj); |
| | | this.popVisible = false; |
| | | }, |
| | | customCell(record) { |
| | | return { |
| | | on: { |
| | | mouseenter: (e) => this.cellMouseenter(e, record), |
| | | mouseleave: (e) => this.cellMouseleave(e, record), |
| | | }, |
| | | }; |
| | | }, |
| | | beforeUpload() { |
| | | return false; |
| | | }, |
| | | uploadChange(data) { |
| | | const { file, fileList } = data; |
| | | if (fileList.length > 1) { |
| | | fileList.shift(); |
| | | } |
| | | if (fileList.length) { |
| | | this.file = fileList[0].originFileObj; |
| | | } else { |
| | | this.file = null; |
| | | } |
| | | }, |
| | | uploadChange1(data) { |
| | | const { file, fileList } = data; |
| | | if (fileList.length > 1) { |
| | | fileList.shift(); |
| | | } |
| | | if (fileList.length) { |
| | | this.file1 = fileList[0].originFileObj; |
| | | } else { |
| | | this.file1 = null; |
| | | this.resObj = []; |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file1); |
| | | fileParse(formData) |
| | | .then((res) => { |
| | | this.$layer.close(loading); |
| | | let { code, data, data2, msg } = res.data; |
| | | if (code && data) { |
| | | let rowId = this.resObj.rowId; |
| | | this.resObj = data2; |
| | | this.resObj.id = rowId; |
| | | this.$message.success("解析成功"); |
| | | } else { |
| | | this.$message.error(msg); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | resize() { |
| | | setTimeout(() => { |
| | | this.update = Math.random(); |
| | | }, 200); |
| | | }, |
| | | activeFN() { |
| | | this.resize(); |
| | | }, |
| | | onSearch(conditions, searchOptions, col) { |
| | | // console.log(conditions); |
| | | // console.log(searchOptions, "00", col); |
| | | this.pageCurr = 1; |
| | | this.conditions = conditions; |
| | | if ("parentType" == col.dataIndex) { |
| | | this.parentTypeChange(col.search.value); |
| | | } |
| | | this.searchData(); |
| | | }, |
| | | onPageChange(page, pageSize) { |
| | | this.pageCurr = page; |
| | | this.pageSize = pageSize; |
| | | this.searchData(); |
| | | }, |
| | | onSizeChange(current, size) { |
| | | this.pageCurr = 1; |
| | | this.pageSize = size; |
| | | this.searchData(); |
| | | }, |
| | | onRefresh(conditions) { |
| | | this.conditions = conditions; |
| | | this.searchData(); |
| | | }, |
| | | onReset(conditions) { |
| | | this.conditions = conditions; |
| | | this.searchData(); |
| | | }, |
| | | // 文件类型查询条件发生变化 查询子文件类型列表 重置子文件类型值 |
| | | parentTypeChange(val) { |
| | | let _search = this.columns[1].search; |
| | | _search.value = []; |
| | | this.conditions["chileType"] = []; |
| | | this.getSopType2(val); |
| | | }, |
| | | searchData() { |
| | | const { pageCurr, pageSize, conditions, columns } = this; |
| | | let params = { pageCurr, pageSize }; |
| | | let data = {}; |
| | | Object.keys(conditions).forEach((v) => { |
| | | switch (v) { |
| | | case "code": |
| | | case "model": |
| | | params[v] = conditions[v]; |
| | | break; |
| | | case "status": |
| | | params[v] = conditions[v]?1:0; |
| | | break; |
| | | case "parentType": |
| | | case "chileType": |
| | | data[v] = conditions[v]; |
| | | break; |
| | | } |
| | | }); |
| | | params.status = 1; |
| | | params.code = this.parentCode; |
| | | let list = []; |
| | | let params2 = "{}" == JSON.stringify(data) ? [] : [data]; |
| | | getList(params, params2) |
| | | .then((res) => { |
| | | let { code, data, data2 } = res.data; |
| | | let total = 0; |
| | | if (code && data) { |
| | | // console.log(data2); |
| | | list = data2.list; |
| | | total = data2.total; |
| | | } |
| | | this.dataSource = list.map(item=>{ |
| | | const fileInfo = getFileTypeAndName(item.fileUrl); |
| | | item.isCanPreview = fileInfo.type === "pdf"; |
| | | return item; |
| | | }); |
| | | this.total = total; |
| | | this.getSopType1(); |
| | | if (-1 == this.update) { |
| | | this.update = Math.random(); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | }); |
| | | }, |
| | | downloadFile(record) { |
| | | const fileInfo = getFileTypeAndName(record.fileUrl); |
| | | let url = this.webUrl + record.fileUrl; |
| | | if(fileInfo.type === 'pdf') { // 预览 |
| | | window.open(url); |
| | | }else { // 下载 |
| | | let loading = this.$layer.loading(); |
| | | let link = document.createElement("a"); |
| | | link.style.display = "none"; |
| | | let fileName = record.fileUrl.split("/").pop(); |
| | | link.href = url; |
| | | link.download = fileName; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | this.$layer.close(loading); |
| | | document.body.removeChild(link); |
| | | } |
| | | }, |
| | | reasonCancel() { |
| | | this.reasonVisible = false; |
| | | }, |
| | | reasonOk() { |
| | | let { id, status } = this.currentObj; |
| | | let reason = this.reason; |
| | | status = status == 0 ? 1 : 0; |
| | | sopLock(id, status, reason).then((res) => { |
| | | const { code } = res.data; |
| | | if (code) { |
| | | this.$message.success("操作成功"); |
| | | this.reasonVisible = false; |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | lock(record) { |
| | | this.reason = ""; |
| | | this.currentObj = record; |
| | | this.reasonVisible = true; |
| | | }, |
| | | viewLog(obj) { |
| | | // console.log(obj); |
| | | const { id, fileVersion } = obj; |
| | | getLogList(id).then((res) => { |
| | | const { code, data, data2 } = res.data; |
| | | if (code) { |
| | | this.logList = data2.map((v) => ({ ...v, fileVersion })); |
| | | this.logVisible = true; |
| | | } else { |
| | | this.$message.error("日志查询失败"); |
| | | } |
| | | }); |
| | | }, |
| | | logCancel() { |
| | | this.logVisible = false; |
| | | }, |
| | | pdfCancel() { |
| | | this.pdfInfo.visible = false; |
| | | }, |
| | | goHistory(record) { |
| | | let { fileName } = record; |
| | | this.$router.push({ |
| | | path: "/resource/sop-history", |
| | | query: { fileName }, |
| | | }); |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.searchData(); |
| | | this.searchAllUserList(); |
| | | this.getSopType1(); |
| | | window.addEventListener("resize", this.resize); |
| | | }, |
| | | destroyed() { |
| | | window.removeEventListener("resize", this.resize); |
| | | }, |
| | | if ( |
| | | this.rowFileName.toLowerCase() != this.resObj.fileName.toLowerCase() |
| | | ) { |
| | | this.$message.error("说明文件与该条记录可能不匹配"); |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | updateSop(this.resObj) |
| | | .then((res) => { |
| | | let { code, data, msg } = res.data; |
| | | if (code) { |
| | | this.uploadShow = false; |
| | | this.$message.success("上传成功"); |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error("解析失败"); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | getSopType1() { |
| | | getSopType1() |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | let list = []; |
| | | if (code) { |
| | | list = data.map((v) => ({ |
| | | title: v.type1, |
| | | value: v.type1, |
| | | })); |
| | | } |
| | | this.columns[0].search.selectOptions = list; |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | }); |
| | | }, |
| | | getSopType2(type) { |
| | | if (type) { |
| | | getSopType2(type) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | let list = []; |
| | | if (code) { |
| | | list = data.map((v) => ({ |
| | | title: v.type2, |
| | | value: v.type2, |
| | | })); |
| | | } |
| | | this.columns[1].search.selectOptions = list; |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | }); |
| | | } else { |
| | | this.columns[1].search.selectOptions = []; |
| | | } |
| | | }, |
| | | cellMouseenter(e, obj) { |
| | | // console.log("enter", e, obj); |
| | | const wraper = this.$refs.wraper; |
| | | const { clientHeight, clientWidth } = wraper; |
| | | const { target, clientX, clientY } = e; |
| | | let { left: x, top: y } = offset(wraper); |
| | | x = clientX - x; |
| | | y = clientY - y; |
| | | // 如果clientHeight 小于380 * 2 则左右布局 |
| | | let dir = "bottom"; |
| | | if (clientHeight < 380 * 2) { |
| | | if (x + 420 + 18 > clientWidth) { |
| | | dir = "left"; |
| | | } else { |
| | | dir = "right"; |
| | | } |
| | | if (y < 180) { |
| | | y = 180; |
| | | } else if (y > clientHeight - 378) { |
| | | y = clientHeight / 2; |
| | | } |
| | | } else { |
| | | if (y + 18 + 360 > clientHeight) { |
| | | // y = clientHeight - 378; |
| | | dir = "top"; |
| | | } else { |
| | | dir = "bottom"; |
| | | } |
| | | if (x < 400) { |
| | | x = 400; |
| | | } |
| | | if (x + 400 > clientWidth) { |
| | | x = clientWidth - 400; |
| | | } |
| | | } |
| | | this.popPosition.x = x; |
| | | this.popPosition.y = y; |
| | | this.popPosition.dir = dir; |
| | | this.popInfo = obj; |
| | | this.popVisible = true; |
| | | }, |
| | | cellMouseleave(e, obj) { |
| | | // console.log("leave", obj); |
| | | this.popVisible = false; |
| | | }, |
| | | customCell(record) { |
| | | return { |
| | | on: { |
| | | mouseenter: (e) => this.cellMouseenter(e, record), |
| | | mouseleave: (e) => this.cellMouseleave(e, record), |
| | | }, |
| | | }; |
| | | }, |
| | | beforeUpload() { |
| | | return false; |
| | | }, |
| | | uploadChange(data) { |
| | | const { file, fileList } = data; |
| | | if (fileList.length > 1) { |
| | | fileList.shift(); |
| | | } |
| | | if (fileList.length) { |
| | | this.file = fileList[0].originFileObj; |
| | | } else { |
| | | this.file = null; |
| | | } |
| | | }, |
| | | uploadChange1(data) { |
| | | const { file, fileList } = data; |
| | | if (fileList.length > 1) { |
| | | fileList.shift(); |
| | | } |
| | | if (fileList.length) { |
| | | this.file1 = fileList[0].originFileObj; |
| | | } else { |
| | | this.file1 = null; |
| | | this.resObj = []; |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file1); |
| | | fileParse(formData) |
| | | .then((res) => { |
| | | this.$layer.close(loading); |
| | | let { code, data, data2, msg } = res.data; |
| | | if (code && data) { |
| | | let rowId = this.resObj.rowId; |
| | | this.resObj = data2; |
| | | this.resObj.id = rowId; |
| | | this.$message.success("解析成功"); |
| | | } else { |
| | | this.$message.error(msg); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | resize() { |
| | | setTimeout(() => { |
| | | this.update = Math.random(); |
| | | }, 200); |
| | | }, |
| | | activeFN() { |
| | | this.resize(); |
| | | }, |
| | | onSearch(conditions, searchOptions, col) { |
| | | // console.log(conditions); |
| | | // console.log(searchOptions, "00", col); |
| | | this.pageCurr = 1; |
| | | this.conditions = conditions; |
| | | if ("parentType" == col.dataIndex) { |
| | | this.parentTypeChange(col.search.value); |
| | | } |
| | | this.searchData(); |
| | | }, |
| | | onPageChange(page, pageSize) { |
| | | this.pageCurr = page; |
| | | this.pageSize = pageSize; |
| | | this.searchData(); |
| | | }, |
| | | onSizeChange(current, size) { |
| | | this.pageCurr = 1; |
| | | this.pageSize = size; |
| | | this.searchData(); |
| | | }, |
| | | onRefresh(conditions) { |
| | | this.conditions = conditions; |
| | | this.searchData(); |
| | | }, |
| | | onReset(conditions) { |
| | | this.conditions = conditions; |
| | | this.searchData(); |
| | | }, |
| | | // 文件类型查询条件发生变化 查询子文件类型列表 重置子文件类型值 |
| | | parentTypeChange(val) { |
| | | let _search = this.columns[1].search; |
| | | _search.value = []; |
| | | this.conditions["chileType"] = []; |
| | | this.getSopType2(val); |
| | | }, |
| | | searchData() { |
| | | const { pageCurr, pageSize, conditions, columns } = this; |
| | | let params = { pageCurr, pageSize }; |
| | | let data = {}; |
| | | Object.keys(conditions).forEach((v) => { |
| | | switch (v) { |
| | | // case "code": |
| | | // case "model": |
| | | // break; |
| | | case "status": |
| | | params[v] = conditions[v] ? 1 : 0; |
| | | break; |
| | | case "parentType": |
| | | case "chileType": |
| | | data[v] = conditions[v]; |
| | | break; |
| | | |
| | | default: |
| | | params[v] = conditions[v]; |
| | | break; |
| | | } |
| | | }); |
| | | params.status = 1; |
| | | params.code = this.parentCode; |
| | | let list = []; |
| | | let params2 = "{}" == JSON.stringify(data) ? [] : [data]; |
| | | getList(params, params2) |
| | | .then((res) => { |
| | | let { code, data, data2 } = res.data; |
| | | let total = 0; |
| | | if (code && data) { |
| | | // console.log(data2); |
| | | list = data2.list; |
| | | total = data2.total; |
| | | } |
| | | this.dataSource = list.map((item) => { |
| | | const fileInfo = getFileTypeAndName(item.fileUrl); |
| | | item.isCanPreview = fileInfo.type === "pdf"; |
| | | return item; |
| | | }); |
| | | this.total = total; |
| | | this.getSopType1(); |
| | | if (-1 == this.update) { |
| | | this.update = Math.random(); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | }); |
| | | }, |
| | | downloadFile(record) { |
| | | const fileInfo = getFileTypeAndName(record.fileUrl); |
| | | let url = this.webUrl + record.fileUrl; |
| | | if (fileInfo.type === "pdf") { |
| | | // 预览 |
| | | window.open(url); |
| | | } else { |
| | | // 下载 |
| | | let loading = this.$layer.loading(); |
| | | let link = document.createElement("a"); |
| | | link.style.display = "none"; |
| | | let fileName = record.fileUrl.split("/").pop(); |
| | | link.href = url; |
| | | link.download = fileName; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | this.$layer.close(loading); |
| | | document.body.removeChild(link); |
| | | } |
| | | }, |
| | | reasonCancel() { |
| | | this.reasonVisible = false; |
| | | }, |
| | | reasonOk() { |
| | | let { id, status } = this.currentObj; |
| | | let reason = this.reason; |
| | | status = status == 0 ? 1 : 0; |
| | | sopLock(id, status, reason).then((res) => { |
| | | const { code } = res.data; |
| | | if (code) { |
| | | this.$message.success("操作成功"); |
| | | this.reasonVisible = false; |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | lock(record) { |
| | | this.reason = ""; |
| | | this.currentObj = record; |
| | | this.reasonVisible = true; |
| | | }, |
| | | viewLog(obj) { |
| | | // console.log(obj); |
| | | const { id, fileVersion } = obj; |
| | | getLogList(id).then((res) => { |
| | | const { code, data, data2 } = res.data; |
| | | if (code) { |
| | | this.logList = data2.map((v) => ({ ...v, fileVersion })); |
| | | this.logVisible = true; |
| | | } else { |
| | | this.$message.error("日志查询失败"); |
| | | } |
| | | }); |
| | | }, |
| | | logCancel() { |
| | | this.logVisible = false; |
| | | }, |
| | | pdfCancel() { |
| | | this.pdfInfo.visible = false; |
| | | }, |
| | | goHistory(record) { |
| | | let { fileName } = record; |
| | | this.$router.push({ |
| | | path: "/resource/sop-history", |
| | | query: { fileName }, |
| | | }); |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.searchData(); |
| | | this.searchAllUserList(); |
| | | this.getSopType1(); |
| | | 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; |
| | | } |
| | | 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; |
| | | } |
| | | } |
| | | 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; |
| | | table-layout: fixed; |
| | | } |
| | | .modal-footer { |
| | | text-align: right; |
| | | button + button { |
| | | margin-left: 8px; |
| | | } |
| | | text-align: right; |
| | | button + button { |
| | | margin-left: 8px; |
| | | } |
| | | } |
| | | .label { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | padding-right: 0.4em; |
| | | height: 32px; |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | padding-right: 0.4em; |
| | | height: 32px; |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | } |
| | | .row ~ .row { |
| | | margin-top: 10px; |
| | | margin-top: 10px; |
| | | } |
| | | .sub-title { |
| | | font-size: 14px; |
| | | font-weight: 700; |
| | | margin-top: 10px; |
| | | font-size: 14px; |
| | | font-weight: 700; |
| | | margin-top: 10px; |
| | | } |
| | | .res-content { |
| | | max-height: 260px; |
| | | overflow-y: auto; |
| | | margin-bottom: 10px; |
| | | max-height: 260px; |
| | | overflow-y: auto; |
| | | margin-bottom: 10px; |
| | | } |
| | | .btn-grp button { |
| | | width: 6.4em; |
| | | width: 6.4em; |
| | | } |
| | | .tag-all { |
| | | margin: 0; |
| | | margin: 0; |
| | | } |
| | | /deep/ .ant-table-fixed-right { |
| | | .ant-table-body-outer { |
| | | margin-bottom: 0 !important; |
| | | } |
| | | .ant-table-body-inner { |
| | | overflow-x: hidden; |
| | | } |
| | | .ant-table-body-outer { |
| | | margin-bottom: 0 !important; |
| | | } |
| | | .ant-table-body-inner { |
| | | overflow-x: hidden; |
| | | } |
| | | } |
| | | .log-content { |
| | | max-height: 400px; |
| | | overflow-y: auto; |
| | | max-height: 400px; |
| | | overflow-y: auto; |
| | | |
| | | .user { |
| | | color: #23aaf2; |
| | | font-weight: 700; |
| | | } |
| | | .user { |
| | | color: #23aaf2; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .time { |
| | | color: #f9be13; |
| | | font-weight: 700; |
| | | } |
| | | .time { |
| | | color: #f9be13; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .version { |
| | | color: #0aedb2; |
| | | font-weight: 700; |
| | | } |
| | | .version { |
| | | color: #0aedb2; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .ant-timeline-item:first-of-type { |
| | | padding-top: 6px; |
| | | } |
| | | .ant-timeline-item:first-of-type { |
| | | padding-top: 6px; |
| | | } |
| | | } |
| | | </style> |