| | |
| | | <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="{ x: 2020, 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" |
| | | > |
| | | <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="{ x: 2020, 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> |
| | | <span class="title">软件中心</span> |
| | | <a-button |
| | | v-if="canUploadSoftware" |
| | | type="primary" |
| | | @click="showUpload" |
| | | >上传软件</a-button |
| | | > |
| | | <a-button v-if="canUploadSoftware" type="primary" @click="showUpload">上传软件</a-button> |
| | | </a-space> |
| | | </template> |
| | | <template slot="tags" slot-scope="tags"> |
| | | <a-tag :color="tags.record.codeFlag ? 'green' : 'red'">{{ tags.text }}</a-tag> |
| | | </template> |
| | | <template slot="action" slot-scope="{ record }"> |
| | | <a-popover title="" trigger="hover"> |
| | | <div class="" slot="content" style="width: 450px"> |
| | | <a-table |
| | | size="small" |
| | | :scroll="{ y: 300 }" |
| | | bordered |
| | | :columns="prodsColumns" |
| | | :data-source="record.links" |
| | | :pagination="false" |
| | | :expandRowByClick="true" |
| | | :row-key="(record1, index) => index" |
| | | > |
| | | <a-table size="small" :scroll="{ y: 300 }" bordered :columns="prodsColumns" :data-source="record.links" |
| | | :pagination="false" :expandRowByClick="true" :row-key="(record1, index) => index"> |
| | | </a-table> |
| | | </div> |
| | | <a>适用机型</a> |
| | | </a-popover> |
| | | <template v-if="canDownloadSoftware"> |
| | | <a-divider type="vertical"></a-divider> |
| | | <a |
| | | :disabled="!!record.soft.lockFlag && !isTester" |
| | | @click="download(record)" |
| | | >下载</a |
| | | > |
| | | <a :disabled="!!record.soft.lockFlag && !isTester" @click="download(record)">下载</a> |
| | | <a-divider type="vertical"></a-divider> |
| | | </template> |
| | | <a-popover title="" trigger="hover"> |
| | | <a-space class="btn-grp" direction="vertical" slot="content"> |
| | | <a-button |
| | | v-if="canUploadSoftware" |
| | | :disabled="!!record.soft.lockFlag" |
| | | type="primary" |
| | | @click="updateDesc(record)" |
| | | >更新说明</a-button |
| | | > |
| | | <a-button |
| | | v-if="record.soft.lockFlag !== -1 ? canLock : isTester" |
| | | type="primary" |
| | | @click="lock(record)" |
| | | >{{ record.soft.lockFlag ? "解锁" : "锁定" }}</a-button |
| | | > |
| | | <a-button |
| | | v-if="canUploadSoftware" |
| | | type="primary" |
| | | @click="handleEmailShow(record)" |
| | | >邮件通知</a-button |
| | | > |
| | | <a-button |
| | | type="primary" |
| | | :disabled="!isTester" |
| | | @click="handleConfirmDelete(record)" |
| | | >删除</a-button |
| | | > |
| | | <a-button v-if="canUploadSoftware" :disabled="!!record.soft.lockFlag" type="primary" |
| | | @click="updateDesc(record)">更新说明</a-button> |
| | | <a-button v-if="record.soft.lockFlag !== -1 ? canLock : isTester" type="primary" |
| | | @click="lock(record)">{{ record.soft.lockFlag ? "解锁" : "锁定" }}</a-button> |
| | | <a-button v-if="canUploadSoftware" type="primary" @click="handleEmailShow(record)">邮件通知</a-button> |
| | | <a-button type="primary" :disabled="!isTester" @click="handleConfirmDelete(record)">删除</a-button> |
| | | <template v-if="isCoder"> |
| | | <a-button type="primary" v-if="record.codeFlag" @click="downloadSource(record)">下载源码</a-button> |
| | | <a-button type="primary" @click="uploadSourceClick(record)">上传源码</a-button> |
| | | </template> |
| | | </a-space> |
| | | <a>更多</a> |
| | | </a-popover> |
| | |
| | | </a-spin> |
| | | </div> |
| | | <!-- 上传软件 --> |
| | | <a-modal |
| | | :visible="uploadShow" |
| | | :footer="null" |
| | | :width="760" |
| | | :title="onlyXls ? '更新发布说明' : '上传软件'" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | @cancel="uploadCancel" |
| | | > |
| | | <a-modal :visible="uploadShow" :footer="null" :width="760" :title="onlyXls ? '更新发布说明' : '上传软件'" :destroyOnClose="true" |
| | | :maskClosable="false" @cancel="uploadCancel"> |
| | | <div class=""> |
| | | <template v-if="!onlyXls"> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">更新时间</a-col> |
| | | <a-col :flex="1"> |
| | | <a-date-picker |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | valueFormat="YYYY-MM-DD HH:mm:ss" |
| | | :allowClear="false" |
| | | :disabled-date="disabledDate" |
| | | :show-time="{ defaultValue: moment('00:00:00', 'HH:mm:ss') }" |
| | | v-model="versionTime" |
| | | /> |
| | | <a-date-picker format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" :allowClear="false" |
| | | :disabled-date="disabledDate" :show-time="{ defaultValue: moment('00:00:00', 'HH:mm:ss') }" |
| | | v-model="versionTime" /> |
| | | </a-col> |
| | | </a-row> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">软件包</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | | class="upload" |
| | | :before-upload="beforeUpload" |
| | | @change="uploadChange" |
| | | accept=".zip,.rar" |
| | | > |
| | | <a-upload class="upload" :before-upload="beforeUpload" @change="uploadChange" accept=".zip,.rar"> |
| | | <a-button type="primary">选择软件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">软件说明</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload |
| | | class="upload" |
| | | :before-upload="beforeUpload" |
| | | @change="uploadChange1" |
| | | accept=".xls,.xlsx" |
| | | > |
| | | <a-upload class="upload" :before-upload="beforeUpload" @change="uploadChange1" accept=".xls,.xlsx"> |
| | | <a-button type="primary">说明文件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | |
| | | </div> |
| | | </div> |
| | | </a-modal> |
| | | <pop |
| | | :visible.sync="popVisible" |
| | | :x="popPosition.x" |
| | | :y="popPosition.y" |
| | | :info="popInfo" |
| | | :position="popPosition.dir" |
| | | ></pop> |
| | | <pop :visible.sync="popVisible" :x="popPosition.x" :y="popPosition.y" :info="popInfo" :position="popPosition.dir"> |
| | | </pop> |
| | | <!-- 操作原因 --> |
| | | <a-modal |
| | | :visible="reasonVisible" |
| | | :width="460" |
| | | title="操作原因" |
| | | :destroyOnClose="true" |
| | | :maskClosable="false" |
| | | @cancel="reasonCancel" |
| | | @ok="reasonOk" |
| | | > |
| | | <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-input type="textarea" v-model="reason" placeHolder="请输入操作原因" /> |
| | | </a-form-model-item> |
| | | </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" |
| | | v-if="emailShow" |
| | | ></email-card> |
| | | <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" |
| | | v-if="emailShow"></email-card> |
| | | </a-modal> |
| | | |
| | | <!-- 上传源码包 --> |
| | | <a-modal :visible="uploadSourceShow" :footer="null" :width="760" title="上传软件源码包" :destroyOnClose="true" |
| | | :maskClosable="false" @cancel="uploadSourceCancel"> |
| | | <div class=""> |
| | | <template> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">对应软件</a-col> |
| | | <a-col :flex="1"> |
| | | <a-select mode="multiple" placeholder="请选择对应的软件" show-search v-model="names" style="width: 36em;"> |
| | | <a-select-option v-for="(item, idx) in otherSoftList" :key="'soft_' + idx" :value="item.fileName"> |
| | | {{ item.fileName }} <span class="version">({{ item.version }})</span> |
| | | </a-select-option> |
| | | </a-select> |
| | | </a-col> |
| | | </a-row> |
| | | <a-row type="flex" class="row"> |
| | | <a-col flex="6em" class="label">软件源码包</a-col> |
| | | <a-col :flex="1"> |
| | | <a-upload class="upload" :before-upload="beforeUpload" @change="sourceUploadChange" accept=".zip,.rar"> |
| | | <a-button type="primary">选择软件</a-button> |
| | | </a-upload> |
| | | </a-col> |
| | | </a-row> |
| | | </template> |
| | | |
| | | <div class="modal-footer"> |
| | | <a-button type="danger" @click="uploadSourceCancel"> 取消 </a-button> |
| | | <a-button type="primary" @click="uploadSource"> 提交 </a-button> |
| | | </div> |
| | | </div> |
| | | </a-modal> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import AdvanceTable from "@/components/table/advance/AdvanceTable"; |
| | | import checkPermit from "@/assets/js/tools/checkPermit"; |
| | | import PERMITS from "@/assets/js/const/const_permits"; |
| | | import DescRes from "./descRes"; |
| | | import Pop from "./pop"; |
| | | import offset from "@/assets/js/tools/offset"; |
| | | import moment from "moment"; |
| | | import { getUserList } from "../../permission/apis"; |
| | | import AdvanceTable from "@/components/table/advance/AdvanceTable"; |
| | | import checkPermit from "@/assets/js/tools/checkPermit"; |
| | | import PERMITS from "@/assets/js/const/const_permits"; |
| | | import DescRes from "./descRes"; |
| | | import Pop from "./pop"; |
| | | import offset from "@/assets/js/tools/offset"; |
| | | import moment from "moment"; |
| | | import { getUserList } from "../../permission/apis"; |
| | | |
| | | import { message, Modal } from "ant-design-vue"; |
| | | import { message, Modal } from "ant-design-vue"; |
| | | |
| | | import { |
| | | getList, |
| | | downLoadSoftware, |
| | | excelParse, |
| | | productSoftwareSubmit, |
| | | applyModel, |
| | | updateSoftwareLock, |
| | | deleteSoftwareApi, |
| | | } from "./apis"; |
| | | import { mapGetters } from "vuex"; |
| | | import EmailCard from "../../components/emailCard"; |
| | | import { |
| | | searchDefaultMailUser, |
| | | sendMail, |
| | | } from "../../components/emailCard/apis"; |
| | | import { |
| | | getList, |
| | | downLoadSoftware, |
| | | excelParse, |
| | | productSoftwareSubmit, |
| | | applyModel, |
| | | updateSoftwareLock, |
| | | deleteSoftwareApi, |
| | | downLoadCode, |
| | | getFileNameByCreateTime, |
| | | uploadCode, |
| | | } from "./apis"; |
| | | import { mapGetters } from "vuex"; |
| | | import EmailCard from "../../components/emailCard"; |
| | | import { |
| | | searchDefaultMailUser, |
| | | sendMail, |
| | | } from "../../components/emailCard/apis"; |
| | | |
| | | import { getRoleUser } from "@/pages/user/apis"; |
| | | // TODO |
| | | // const tester = ["李桂华"]; |
| | | import { getRoleUser } from "@/pages/user/apis"; |
| | | // TODO |
| | | // const tester = ["李桂华"]; |
| | | |
| | | export default { |
| | | name: "", |
| | | data() { |
| | | return { |
| | | mailList: [], |
| | | tester: [], |
| | | versionTime: moment().format("YYYY-MM-DD HH:mm:ss"), |
| | | reasonVisible: false, |
| | | reason: "", |
| | | currentObj: null, |
| | | popVisible: false, |
| | | popPosition: { |
| | | x: 0, |
| | | y: 0, |
| | | dir: "bottom", |
| | | }, |
| | | popInfo: [], |
| | | onlyXls: false, |
| | | resData: [], |
| | | file: null, |
| | | file1: null, |
| | | uploadShow: false, |
| | | spinning: false, |
| | | loading: false, |
| | | pageCurr: 1, |
| | | pageSize: 10, |
| | | total: 0, |
| | | y: 400, |
| | | update: -1, |
| | | conditions: {}, |
| | | columns: [ |
| | | { |
| | | fixed: "left", |
| | | title: "序号", |
| | | dataIndex: "dataIndex", |
| | | key: "dataIndex", |
| | | align: "center", |
| | | width: 60, |
| | | noSearch: true, |
| | | scopedSlots: { customRender: "dataIndex" }, |
| | | }, |
| | | { |
| | | title: "状态", |
| | | dataIndex: "soft.lockFlag", |
| | | dataType: "select", |
| | | align: "center", |
| | | width: 140, |
| | | visible: false, |
| | | searchAble: true, |
| | | noSearch: true, |
| | | search: { |
| | | default: 0, |
| | | selectOptions: [ |
| | | { |
| | | title: "全部", |
| | | value: 11, |
| | | }, |
| | | { |
| | | title: "可用", |
| | | value: 0, |
| | | }, |
| | | { |
| | | title: "不可用", |
| | | value: 12, |
| | | }, |
| | | { |
| | | title: "待测试", |
| | | value: -1, |
| | | }, |
| | | ], |
| | | }, |
| | | // customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "名称", |
| | | dataIndex: "soft.fileName", |
| | | align: "center", |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "上传日期", |
| | | dataIndex: "soft.createTime", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "类型", |
| | | dataIndex: "soft.type", |
| | | align: "center", |
| | | width: 180, |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "版本", |
| | | dataIndex: "soft.version", |
| | | align: "center", |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "负责人", |
| | | dataIndex: "soft.owner", |
| | | align: "center", |
| | | searchAble: true, |
| | | width: 160, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "适用机型号", |
| | | dataIndex: "applyModel", |
| | | align: "center", |
| | | searchAble: true, |
| | | visible: false, |
| | | }, |
| | | { |
| | | title: "适用机料号", |
| | | dataIndex: "applyMaterialCode", |
| | | align: "center", |
| | | searchAble: true, |
| | | visible: false, |
| | | }, |
| | | { |
| | | title: "板号", |
| | | dataIndex: "soft.boardNumber", |
| | | align: "center", |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "升级说明", |
| | | dataIndex: "soft.releaseNotes", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "最后一次操作原因", |
| | | dataIndex: "soft.localReason", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "操作", |
| | | dataIndex: "operation", |
| | | align: "center", |
| | | width: 228, |
| | | fixed: "right", |
| | | scopedSlots: { customRender: "action" }, |
| | | noSearch: true, |
| | | }, |
| | | ], |
| | | dataSource: [], |
| | | prodsColumns: [ |
| | | { |
| | | title: "型号", |
| | | dataIndex: "applyModel", |
| | | align: "center", |
| | | searchAble: true, |
| | | }, |
| | | { |
| | | title: "料号", |
| | | dataIndex: "applyMaterialCode", |
| | | align: "center", |
| | | width: 180, |
| | | noSearch: true, |
| | | }, |
| | | ], |
| | | emailShow: false, |
| | | emailInfo: { |
| | | title: "", |
| | | content: "", |
| | | }, |
| | | userList: [], |
| | | }; |
| | | }, |
| | | components: { |
| | | EmailCard, |
| | | AdvanceTable, |
| | | DescRes, |
| | | Pop, |
| | | }, |
| | | methods: { |
| | | moment, |
| | | rowClassFn(record) { |
| | | let classList = []; |
| | | if (record.soft.lockFlag == -1) { |
| | | classList.push("locked"); |
| | | } |
| | | return classList; |
| | | }, |
| | | disabledDate(current) { |
| | | // Can not select days before today and today |
| | | return current > moment().endOf("day"); |
| | | }, |
| | | onSearch(conditions, searchOptions) { |
| | | // console.log(conditions); |
| | | // console.log(searchOptions, "options"); |
| | | this.pageCurr = 1; |
| | | this.conditions = conditions; |
| | | 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) { |
| | | // console.log(conditions, "reset"); |
| | | this.conditions = conditions; |
| | | this.searchData(); |
| | | }, |
| | | searchData() { |
| | | const { pageCurr, pageSize, conditions } = this; |
| | | let params = {}; |
| | | if (undefined == conditions["soft.lockFlag"]) { |
| | | conditions["soft.lockFlag"] = 11; |
| | | } |
| | | Object.keys(conditions).forEach((v) => { |
| | | switch (v) { |
| | | case "soft.lockFlag": |
| | | params["lockFlag"] = conditions[v]; |
| | | break; |
| | | case "soft.fileName": |
| | | params["fileName"] = conditions[v]; |
| | | break; |
| | | case "soft.owner": |
| | | params["owner"] = conditions[v]; |
| | | break; |
| | | case "soft.boardNumber": |
| | | params["boardNumber"] = conditions[v]; |
| | | break; |
| | | case "soft.version": |
| | | params["version"] = conditions[v]; |
| | | break; |
| | | default: |
| | | params[v] = conditions[v]; |
| | | break; |
| | | } |
| | | }); |
| | | getList(pageCurr, pageSize, params).then((res) => { |
| | | res = res.data; |
| | | // console.log(res); |
| | | let data = []; |
| | | let total = 0; |
| | | if (res.code && res.data) { |
| | | data = res.data2.list.map((v) => { |
| | | let soft = v.softwares[0]; |
| | | return { |
| | | id: soft.id, |
| | | soft, |
| | | links: v.softwares, |
| | | }; |
| | | }); |
| | | total = res.data2.total; |
| | | } |
| | | this.dataSource = data; |
| | | this.total = total; |
| | | if (-1 == this.update) { |
| | | this.update = Math.random(); |
| | | } |
| | | }); |
| | | }, |
| | | download(obj) { |
| | | const { id } = obj; |
| | | let loading = this.$layer.loading(); |
| | | downLoadSoftware(id).then((res) => { |
| | | // console.log(res, "==========="); |
| | | 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(); |
| | | this.$layer.close(loading); |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(url); |
| | | } else { |
| | | this.$layer.close(loading); |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | resize() { |
| | | setTimeout(() => { |
| | | this.update = Math.random(); |
| | | }, 200); |
| | | }, |
| | | activeFN() { |
| | | this.resize(); |
| | | }, |
| | | showUpload() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resData = []; |
| | | this.onlyXls = false; |
| | | this.versionTime = moment().format("YYYY-MM-DD HH:mm:ss"); |
| | | this.uploadShow = true; |
| | | }, |
| | | updateDesc() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resData = []; |
| | | this.onlyXls = true; |
| | | this.uploadShow = true; |
| | | }, |
| | | 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.resData = []; |
| | | return false; |
| | | } |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file1); |
| | | excelParse(formData).then((res) => { |
| | | const { code, data, data2, msg } = res.data; |
| | | let list = []; |
| | | if (code && data) { |
| | | list = data2; |
| | | this.$message.success(msg); |
| | | } else { |
| | | this.$message.error("解析失败"); |
| | | } |
| | | this.resData = list; |
| | | }); |
| | | }, |
| | | uploadCancel() { |
| | | this.uploadShow = false; |
| | | }, |
| | | uploadSoftware() { |
| | | if (!this.file) { |
| | | this.$message.error("请选择要上传的软件包"); |
| | | return false; |
| | | } |
| | | if (!this.file1) { |
| | | this.$message.error("请选择软件说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resData.length) { |
| | | this.$message.error("软件说明文件解析异常"); |
| | | return false; |
| | | } |
| | | let info = this.resData[0]; |
| | | if (!info.boardNumber || !info.type) { |
| | | this.$error({ |
| | | title: "系统提示", |
| | | content: "缺少板号或软件类型,请输入板号和软件类型", |
| | | }); |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | export default { |
| | | name: "", |
| | | data() { |
| | | return { |
| | | mailList: [], |
| | | tester: [], |
| | | versionTime: moment().format("YYYY-MM-DD HH:mm:ss"), |
| | | reasonVisible: false, |
| | | reason: "", |
| | | currentObj: null, |
| | | popVisible: false, |
| | | uploadSourceShow: false, |
| | | names: [], |
| | | otherSoftList: [], |
| | | popPosition: { |
| | | x: 0, |
| | | y: 0, |
| | | dir: "bottom", |
| | | }, |
| | | popInfo: [], |
| | | onlyXls: false, |
| | | resData: [], |
| | | file: null, |
| | | file1: null, |
| | | sourceFile: null, |
| | | uploadShow: false, |
| | | spinning: false, |
| | | loading: false, |
| | | pageCurr: 1, |
| | | pageSize: 10, |
| | | total: 0, |
| | | y: 400, |
| | | update: -1, |
| | | conditions: {}, |
| | | columns: [ |
| | | { |
| | | fixed: "left", |
| | | title: "序号", |
| | | dataIndex: "dataIndex", |
| | | key: "dataIndex", |
| | | align: "center", |
| | | width: 60, |
| | | noSearch: true, |
| | | scopedSlots: { customRender: "dataIndex" }, |
| | | }, |
| | | { |
| | | title: "状态", |
| | | dataIndex: "soft.lockFlag", |
| | | dataType: "select", |
| | | align: "center", |
| | | width: 140, |
| | | visible: false, |
| | | searchAble: true, |
| | | noSearch: true, |
| | | search: { |
| | | default: 0, |
| | | selectOptions: [ |
| | | { |
| | | title: "全部", |
| | | value: 11, |
| | | }, |
| | | { |
| | | title: "可用", |
| | | value: 0, |
| | | }, |
| | | { |
| | | title: "不可用", |
| | | value: 12, |
| | | }, |
| | | { |
| | | title: "待测试", |
| | | value: -1, |
| | | }, |
| | | ], |
| | | }, |
| | | // customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "名称", |
| | | dataIndex: "soft.fileName", |
| | | align: "center", |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "上传日期", |
| | | dataIndex: "soft.createTime", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "是否已上传源码", |
| | | dataIndex: "codeFlagStr", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | scopedSlots: { customRender: 'tags' }, |
| | | }, |
| | | { |
| | | title: "源码包名称", |
| | | dataIndex: "codeName", |
| | | align: "center", |
| | | width: 180, |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "类型", |
| | | dataIndex: "soft.type", |
| | | align: "center", |
| | | width: 180, |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "版本", |
| | | dataIndex: "soft.version", |
| | | align: "center", |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "负责人", |
| | | dataIndex: "soft.owner", |
| | | align: "center", |
| | | searchAble: true, |
| | | width: 160, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "适用机型号", |
| | | dataIndex: "applyModel", |
| | | align: "center", |
| | | searchAble: true, |
| | | visible: false, |
| | | }, |
| | | { |
| | | title: "适用机料号", |
| | | dataIndex: "applyMaterialCode", |
| | | align: "center", |
| | | searchAble: true, |
| | | visible: false, |
| | | }, |
| | | { |
| | | title: "板号", |
| | | dataIndex: "soft.boardNumber", |
| | | align: "center", |
| | | searchAble: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "升级说明", |
| | | dataIndex: "soft.releaseNotes", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "最后一次操作原因", |
| | | dataIndex: "soft.localReason", |
| | | align: "center", |
| | | noSearch: true, |
| | | customCell: this.customCell, |
| | | }, |
| | | { |
| | | title: "操作", |
| | | dataIndex: "operation", |
| | | align: "center", |
| | | width: 228, |
| | | fixed: "right", |
| | | scopedSlots: { customRender: "action" }, |
| | | noSearch: true, |
| | | }, |
| | | ], |
| | | dataSource: [], |
| | | prodsColumns: [ |
| | | { |
| | | title: "型号", |
| | | dataIndex: "applyModel", |
| | | align: "center", |
| | | searchAble: true, |
| | | }, |
| | | { |
| | | title: "料号", |
| | | dataIndex: "applyMaterialCode", |
| | | align: "center", |
| | | width: 180, |
| | | noSearch: true, |
| | | }, |
| | | ], |
| | | emailShow: false, |
| | | emailInfo: { |
| | | title: "", |
| | | content: "", |
| | | }, |
| | | userList: [], |
| | | }; |
| | | }, |
| | | components: { |
| | | EmailCard, |
| | | AdvanceTable, |
| | | DescRes, |
| | | Pop, |
| | | }, |
| | | methods: { |
| | | moment, |
| | | rowClassFn(record) { |
| | | let classList = []; |
| | | if (record.soft.lockFlag == -1) { |
| | | classList.push("locked"); |
| | | } |
| | | return classList; |
| | | }, |
| | | disabledDate(current) { |
| | | // Can not select days before today and today |
| | | return current > moment().endOf("day"); |
| | | }, |
| | | onSearch(conditions, searchOptions) { |
| | | // console.log(conditions); |
| | | // console.log(searchOptions, "options"); |
| | | this.pageCurr = 1; |
| | | this.conditions = conditions; |
| | | 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) { |
| | | // console.log(conditions, "reset"); |
| | | this.conditions = conditions; |
| | | this.searchData(); |
| | | }, |
| | | searchData() { |
| | | const { pageCurr, pageSize, conditions } = this; |
| | | let params = {}; |
| | | if (undefined == conditions["soft.lockFlag"]) { |
| | | conditions["soft.lockFlag"] = 11; |
| | | } |
| | | Object.keys(conditions).forEach((v) => { |
| | | switch (v) { |
| | | case "soft.lockFlag": |
| | | params["lockFlag"] = conditions[v]; |
| | | break; |
| | | case "soft.fileName": |
| | | params["fileName"] = conditions[v]; |
| | | break; |
| | | case "soft.owner": |
| | | params["owner"] = conditions[v]; |
| | | break; |
| | | case "soft.boardNumber": |
| | | params["boardNumber"] = conditions[v]; |
| | | break; |
| | | case "soft.version": |
| | | params["version"] = conditions[v]; |
| | | break; |
| | | default: |
| | | params[v] = conditions[v]; |
| | | break; |
| | | } |
| | | }); |
| | | getList(pageCurr, pageSize, params).then((res) => { |
| | | res = res.data; |
| | | // console.log(res); |
| | | let data = []; |
| | | let total = 0; |
| | | if (res.code && res.data) { |
| | | data = res.data2.list.map((v) => { |
| | | let soft = v.softwares[0]; |
| | | return { |
| | | id: soft.id, |
| | | fileName: v.fileName, |
| | | codeFlag: v.codeFlag, |
| | | codeName: v.codeName || '--', |
| | | codeFlagStr: v.codeFlag ? '已上传源码' : '未上传源码', |
| | | soft, |
| | | links: v.softwares, |
| | | }; |
| | | }); |
| | | total = res.data2.total; |
| | | } |
| | | this.dataSource = data; |
| | | this.total = total; |
| | | if (-1 == this.update) { |
| | | this.update = Math.random(); |
| | | } |
| | | }); |
| | | }, |
| | | download(obj) { |
| | | const { id } = obj; |
| | | let loading = this.$layer.loading(); |
| | | downLoadSoftware(id).then((res) => { |
| | | // console.log(res, "==========="); |
| | | 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(); |
| | | this.$layer.close(loading); |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(url); |
| | | } else { |
| | | this.$layer.close(loading); |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | resize() { |
| | | setTimeout(() => { |
| | | this.update = Math.random(); |
| | | }, 200); |
| | | }, |
| | | activeFN() { |
| | | this.resize(); |
| | | }, |
| | | showUpload() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resData = []; |
| | | this.onlyXls = false; |
| | | this.versionTime = moment().format("YYYY-MM-DD HH:mm:ss"); |
| | | this.uploadShow = true; |
| | | }, |
| | | updateDesc() { |
| | | this.file = null; |
| | | this.file1 = null; |
| | | this.resData = []; |
| | | this.onlyXls = true; |
| | | this.uploadShow = true; |
| | | }, |
| | | 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.resData = []; |
| | | return false; |
| | | } |
| | | const formData = new FormData(); |
| | | formData.append("multipartFile", this.file1); |
| | | excelParse(formData).then((res) => { |
| | | const { code, data, data2, msg } = res.data; |
| | | let list = []; |
| | | if (code && data) { |
| | | list = data2; |
| | | this.$message.success(msg); |
| | | } else { |
| | | this.$message.error("解析失败"); |
| | | } |
| | | this.resData = list; |
| | | }); |
| | | }, |
| | | uploadCancel() { |
| | | this.uploadShow = false; |
| | | }, |
| | | uploadSoftware() { |
| | | if (!this.file) { |
| | | this.$message.error("请选择要上传的软件包"); |
| | | return false; |
| | | } |
| | | if (!this.file1) { |
| | | this.$message.error("请选择软件说明文件"); |
| | | return false; |
| | | } |
| | | if (!this.resData.length) { |
| | | this.$message.error("软件说明文件解析异常"); |
| | | return false; |
| | | } |
| | | let info = this.resData[0]; |
| | | if (!info.boardNumber || !info.type) { |
| | | this.$error({ |
| | | title: "系统提示", |
| | | content: "缺少板号或软件类型,请输入板号和软件类型", |
| | | }); |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | |
| | | const formData = new FormData(); |
| | | formData.append("file1", this.file); |
| | | formData.append("file2", this.file1); |
| | | formData.append("fontUpdateTime", this.versionTime); |
| | | formData.append("softwareStr", JSON.stringify(this.resData)); |
| | | productSoftwareSubmit(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); |
| | | }); |
| | | }, |
| | | 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("file1", this.file); |
| | | formData.append("file2", this.file1); |
| | | formData.append("fontUpdateTime", this.versionTime); |
| | | formData.append("softwareStr", JSON.stringify(this.resData)); |
| | | productSoftwareSubmit(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); |
| | | }); |
| | | }, |
| | | 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("解析失败"); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | 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 < 300) { |
| | | x = 300; |
| | | } |
| | | if (x + 300 > clientWidth) { |
| | | x = clientWidth - 300; |
| | | } |
| | | } |
| | | this.popPosition.x = x; |
| | | this.popPosition.y = y; |
| | | this.popPosition.dir = dir; |
| | | this.popInfo = obj.links; |
| | | 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), |
| | | }, |
| | | }; |
| | | }, |
| | | reasonCancel() { |
| | | this.reasonVisible = false; |
| | | }, |
| | | reasonOk() { |
| | | let { |
| | | soft: { fileUrl, lockFlag }, |
| | | } = this.currentObj; |
| | | // 多传一个当前状态 |
| | | let lockFlagNow = lockFlag; |
| | | lockFlag = !lockFlag * 1; |
| | | let params = { |
| | | fileUrl, |
| | | localReason: this.reason, |
| | | lockFlag, |
| | | lockFlagNow, |
| | | }; |
| | | updateSoftwareLock(params).then((res) => { |
| | | const { code, data } = res.data; |
| | | if (code && data) { |
| | | this.$message.success("操作成功"); |
| | | this.reasonVisible = false; |
| | | // 如果是测试人员解锁确认 则自动发送邮件 |
| | | if (lockFlagNow == -1 && this.isTester) { |
| | | this.sendEmail(); |
| | | } |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | sendEmail() { |
| | | let { title, content } = this.handleEmailShow(this.currentObj, true); |
| | | let params = { mailList: this.mailList, title, content }; |
| | | sendMail(params); |
| | | }, |
| | | lock(record) { |
| | | this.reason = ""; |
| | | this.currentObj = record; |
| | | this.reasonVisible = true; |
| | | }, |
| | | handleEmailShow(record, get) { |
| | | this.emailInfo.title = |
| | | "[软件发布记录]" + |
| | | record.soft.fileName + |
| | | " 版本号:" + |
| | | record.soft.version; |
| | | let { soft, links } = record; |
| | | let content = []; |
| | | content.push("软件基本信息"); |
| | | content.push("文件名称: " + soft.fileName); |
| | | content.push("板号: " + soft.boardNumber); |
| | | content.push("软件类型: " + soft.type); |
| | | content.push("软件版本: " + soft.version); |
| | | content.push("软件基于版本: " + soft.basedVersion); |
| | | content.push("软件负责人: " + soft.owner); |
| | | content.push("归档日期: " + soft.filingDate); |
| | | content.push("软件类型: " + soft.type); |
| | | content.push("软件适用机型"); |
| | | links.forEach((v) => { |
| | | content.push( |
| | | "物料编码: " + v.applyMaterialCode + " 规格型号: " + v.applyModel |
| | | ); |
| | | }); |
| | | content.push("发布说明: " + soft.releaseNotes); |
| | | this.emailInfo.content = content.join("\n"); |
| | | if (get) { |
| | | return { |
| | | title: this.emailInfo.title, |
| | | content: content.join("\n"), |
| | | }; |
| | | } |
| | | this.emailShow = true; |
| | | }, |
| | | emailCancel() { |
| | | this.emailShow = false; |
| | | }, |
| | | searchAllUserList() { |
| | | getUserList() |
| | | .then((res) => { |
| | | let rs = res.data; |
| | | if (rs.code && rs.data) { |
| | | this.userList = rs.data2; |
| | | this.searchDefaultMailUser(); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | searchDefaultMailUser() { |
| | | // 软件 type为1 |
| | | let type = 1; |
| | | 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.userList |
| | | .filter((o) => data.includes(o.name) && o.mail) |
| | | .map((item) => { |
| | | return item.mail; |
| | | }); |
| | | }); |
| | | }, |
| | | getRoleUser() { |
| | | getRoleUser(0) |
| | | .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); |
| | | }); |
| | | }, |
| | | handleConfirmDelete(obj) { |
| | | Modal.confirm({ |
| | | content: () => "删除当前软件,删除后无法恢复,请注意!!!", |
| | | onOk: async () => { |
| | | try { |
| | | const res = await deleteSoftwareApi( |
| | | obj.soft.fileName, |
| | | obj.soft.version |
| | | ); |
| | | const rs = res.data; |
| | | if (rs.code === 1 && rs.data) { |
| | | this.$message.success("删除成功。"); |
| | | } else { |
| | | this.$message.error("删除失败!!!"); |
| | | } |
| | | this.searchData(); |
| | | } catch (e) { |
| | | this.$message.error("删除失败,请联系开发人员!!!"); |
| | | console.log(e); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | }, |
| | | 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); |
| | | }, |
| | | }, |
| | | computed: { |
| | | ...mapGetters("account", ["permits", "user"]), |
| | | ...mapGetters("setting", ["affixed"]), |
| | | canUploadSoftware() { |
| | | return checkPermit(PERMITS.uploadSoftware, this.permits); |
| | | }, |
| | | canDownloadSoftware() { |
| | | return checkPermit(PERMITS.downloadSoftware, this.permits); |
| | | }, |
| | | canLock() { |
| | | return checkPermit(PERMITS.lockOther, this.permits); |
| | | }, |
| | | isTester() { |
| | | return this.tester.some((v) => v == this.user.name); |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.getRoleUser(); |
| | | this.searchData(); |
| | | this.searchAllUserList(); |
| | | window.addEventListener("resize", this.resize); |
| | | }, |
| | | destroyed() { |
| | | window.removeEventListener("resize", this.resize); |
| | | }, |
| | | }; |
| | | 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("解析失败"); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | 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 < 300) { |
| | | x = 300; |
| | | } |
| | | if (x + 300 > clientWidth) { |
| | | x = clientWidth - 300; |
| | | } |
| | | } |
| | | this.popPosition.x = x; |
| | | this.popPosition.y = y; |
| | | this.popPosition.dir = dir; |
| | | this.popInfo = obj.links; |
| | | 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), |
| | | }, |
| | | }; |
| | | }, |
| | | reasonCancel() { |
| | | this.reasonVisible = false; |
| | | }, |
| | | reasonOk() { |
| | | let { |
| | | soft: { fileUrl, lockFlag }, |
| | | } = this.currentObj; |
| | | // 多传一个当前状态 |
| | | let lockFlagNow = lockFlag; |
| | | lockFlag = !lockFlag * 1; |
| | | let params = { |
| | | fileUrl, |
| | | localReason: this.reason, |
| | | lockFlag, |
| | | lockFlagNow, |
| | | }; |
| | | updateSoftwareLock(params).then((res) => { |
| | | const { code, data } = res.data; |
| | | if (code && data) { |
| | | this.$message.success("操作成功"); |
| | | this.reasonVisible = false; |
| | | // 如果是测试人员解锁确认 则自动发送邮件 |
| | | if (lockFlagNow == -1 && this.isTester) { |
| | | this.sendEmail(); |
| | | } |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | sendEmail() { |
| | | let { title, content } = this.handleEmailShow(this.currentObj, true); |
| | | let params = { mailList: this.mailList, title, content }; |
| | | sendMail(params); |
| | | }, |
| | | lock(record) { |
| | | this.reason = ""; |
| | | this.currentObj = record; |
| | | this.reasonVisible = true; |
| | | }, |
| | | handleEmailShow(record, get) { |
| | | this.emailInfo.title = |
| | | "[软件发布记录]" + |
| | | record.soft.fileName + |
| | | " 版本号:" + |
| | | record.soft.version; |
| | | let { soft, links } = record; |
| | | let content = []; |
| | | content.push("软件基本信息"); |
| | | content.push("文件名称: " + soft.fileName); |
| | | content.push("板号: " + soft.boardNumber); |
| | | content.push("软件类型: " + soft.type); |
| | | content.push("软件版本: " + soft.version); |
| | | content.push("软件基于版本: " + soft.basedVersion); |
| | | content.push("软件负责人: " + soft.owner); |
| | | content.push("归档日期: " + soft.filingDate); |
| | | content.push("软件类型: " + soft.type); |
| | | content.push("软件适用机型"); |
| | | links.forEach((v) => { |
| | | content.push( |
| | | "物料编码: " + v.applyMaterialCode + " 规格型号: " + v.applyModel |
| | | ); |
| | | }); |
| | | content.push("发布说明: " + soft.releaseNotes); |
| | | this.emailInfo.content = content.join("\n"); |
| | | if (get) { |
| | | return { |
| | | title: this.emailInfo.title, |
| | | content: content.join("\n"), |
| | | }; |
| | | } |
| | | this.emailShow = true; |
| | | }, |
| | | emailCancel() { |
| | | this.emailShow = false; |
| | | }, |
| | | searchAllUserList() { |
| | | getUserList() |
| | | .then((res) => { |
| | | let rs = res.data; |
| | | if (rs.code && rs.data) { |
| | | this.userList = rs.data2; |
| | | this.searchDefaultMailUser(); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | searchDefaultMailUser() { |
| | | // 软件 type为1 |
| | | let type = 1; |
| | | 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.userList |
| | | .filter((o) => data.includes(o.name) && o.mail) |
| | | .map((item) => { |
| | | return item.mail; |
| | | }); |
| | | }); |
| | | }, |
| | | getRoleUser() { |
| | | getRoleUser(0) |
| | | .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); |
| | | }); |
| | | }, |
| | | handleConfirmDelete(obj) { |
| | | Modal.confirm({ |
| | | content: () => "删除当前软件,删除后无法恢复,请注意!!!", |
| | | onOk: async () => { |
| | | try { |
| | | const res = await deleteSoftwareApi( |
| | | obj.soft.fileName, |
| | | obj.soft.version |
| | | ); |
| | | const rs = res.data; |
| | | if (rs.code === 1 && rs.data) { |
| | | this.$message.success("删除成功。"); |
| | | } else { |
| | | this.$message.error("删除失败!!!"); |
| | | } |
| | | this.searchData(); |
| | | } catch (e) { |
| | | this.$message.error("删除失败,请联系开发人员!!!"); |
| | | console.log(e); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | // 查询其他版本 与当前软件上传日期前三天内的列表 |
| | | getOtherSoft(date) { |
| | | return getFileNameByCreateTime(date).then((res) => { |
| | | let { code, data, data2 } = res.data; |
| | | let list = []; |
| | | if (code && data) { |
| | | console.log(data); |
| | | list = data2; |
| | | } |
| | | this.otherSoftList = list; |
| | | return list; |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err); |
| | | return []; |
| | | }); |
| | | |
| | | }, |
| | | sourceUploadChange(data) { |
| | | const { file, fileList } = data; |
| | | if (fileList.length > 1) { |
| | | fileList.shift(); |
| | | } |
| | | if (fileList.length) { |
| | | this.sourceFile = fileList[0].originFileObj; |
| | | } else { |
| | | this.sourceFile = null; |
| | | } |
| | | }, |
| | | // 上传源码包 |
| | | uploadSource(record) { |
| | | if (!this.sourceFile) { |
| | | this.$message.error("请选择要上传的源码包"); |
| | | return false; |
| | | } |
| | | if (!this.names.length) { |
| | | this.$message.error("请选择源码包对应的软件"); |
| | | return false; |
| | | } |
| | | let loading = this.$layer.loading(); |
| | | |
| | | const formData = new FormData(); |
| | | formData.append("file", this.sourceFile); |
| | | formData.append("fileNames", this.names.join(',')); |
| | | uploadCode(formData) |
| | | .then((res) => { |
| | | let { code, data, msg } = res.data; |
| | | if (code) { |
| | | this.uploadSourceShow = false; |
| | | this.$message.success('上传成功'); |
| | | this.searchData(); |
| | | } else { |
| | | this.$message.error('上传失败'); |
| | | } |
| | | this.$layer.close(loading); |
| | | }) |
| | | .catch((error) => { |
| | | this.$layer.close(loading); |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | // 下载源码包 |
| | | downloadSource(record) { |
| | | let loading = this.$layer.loading(); |
| | | downLoadCode(record.fileName).then((res) => { |
| | | 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(); |
| | | this.$layer.close(loading); |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(url); |
| | | } else { |
| | | this.$layer.close(loading); |
| | | this.$message.error("操作失败"); |
| | | } |
| | | }); |
| | | }, |
| | | async uploadSourceClick(obj) { |
| | | console.log('obj', obj, '============='); |
| | | this.currentObj = obj; |
| | | let date = obj.soft.createTime.split(' ')[0]; |
| | | await this.getOtherSoft(date); |
| | | this.names = [obj.fileName]; |
| | | this.uploadSourceShow = true; |
| | | }, |
| | | uploadSourceCancel() { |
| | | this.uploadSourceShow = 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); |
| | | }, |
| | | }, |
| | | computed: { |
| | | ...mapGetters("account", ["permits", "user"]), |
| | | ...mapGetters("setting", ["affixed"]), |
| | | canUploadSoftware() { |
| | | return checkPermit(PERMITS.uploadSoftware, this.permits); |
| | | }, |
| | | canDownloadSoftware() { |
| | | return checkPermit(PERMITS.downloadSoftware, this.permits); |
| | | }, |
| | | canLock() { |
| | | return checkPermit(PERMITS.lockOther, this.permits); |
| | | }, |
| | | isTester() { |
| | | return this.tester.some((v) => v == this.user.name); |
| | | }, |
| | | isCoder() { |
| | | return '李文涛' == this.user.name; |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.getRoleUser(); |
| | | this.searchData(); |
| | | this.searchAllUserList(); |
| | | 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; |
| | |
| | | bottom: 0; |
| | | } |
| | | } |
| | | |
| | | /deep/table { |
| | | table-layout: fixed; |
| | | } |
| | | |
| | | .modal-footer { |
| | | text-align: right; |
| | | button + button { |
| | | |
| | | button+button { |
| | | margin-left: 8px; |
| | | } |
| | | } |
| | | |
| | | .label { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | padding-right: 0.4em; |
| | | height: 32px; |
| | | |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | } |
| | | .row ~ .row { |
| | | |
| | | .row~.row { |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .upload { |
| | | display: flex; |
| | | |
| | | /deep/.ant-upload-list { |
| | | flex: 1; |
| | | position: relative; |
| | | & > div { |
| | | |
| | | &>div { |
| | | position: absolute; |
| | | left: 0; |
| | | right: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .sub-title { |
| | | font-size: 14px; |
| | | font-weight: 700; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .res-content { |
| | | max-height: 260px; |
| | | overflow-y: auto; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .btn-grp button { |
| | | width: 6.4em; |
| | | } |
| | | /deep/.locked > td { |
| | | |
| | | /deep/.locked>td { |
| | | background: #fec54b; |
| | | } |
| | | /deep/.locked.locked.locked.ant-table-row-hover > td, |
| | | /deep/.locked.locked.locked:hover > td { |
| | | |
| | | /deep/.locked.locked.locked.ant-table-row-hover>td, |
| | | /deep/.locked.locked.locked:hover>td { |
| | | background: #fcd583; |
| | | } |
| | | .version { |
| | | color: #090; |
| | | display: inline-block; |
| | | font-weight: bold; |
| | | padding: 0 0.4em; |
| | | margin-left: 0.4em; |
| | | } |
| | | </style> |