对比新文件 |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | export function getConfig(params) { |
| | | return request({ |
| | | url: '/system/config/list', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function addConfig(data) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function editConfig(params) { |
| | | return request({ |
| | | url: `/system/config`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | export function delConfig(data) { |
| | | return request({ |
| | | url: `/system/config/` + data, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getConfigById(params) { |
| | | return request({ |
| | | url: '/system/config/getConfigByUser', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function delPic(path) { |
| | | return request({ |
| | | url: '/system/common/removeFile', |
| | | method: 'delete', |
| | | params: path, |
| | | timeout: 20000 |
| | | }) |
| | | } |
| | |
| | | type: 'warning' |
| | | }).then(() => { |
| | | removeToken() |
| | | Cookies.remove('userInfo') |
| | | Cookies.remove('configInfo') |
| | | location.href = '/homePage'; |
| | | |
| | | }).catch(() => { }); |
| | |
| | | <template> |
| | | <div class="sidebar-logo-container" :class="{ 'collapse': collapse }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"> |
| | | <transition name="sidebarLogoFade"> |
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="firstPage"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" :to="firstPage"> |
| | | <img v-if="logoImg" :src="logoImg" class="sidebar-logo" /> |
| | | <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1> |
| | | </router-link> |
| | | <router-link v-else key="expand" class="sidebar-logo-link" :to="firstPage"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <img v-if="logoImg" :src="logoImg" class="sidebar-logo" /> |
| | | <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1> |
| | | </router-link> |
| | | </transition> |
| | |
| | | required: true |
| | | } |
| | | }) |
| | | const logoImg = ref('') |
| | | const firstPage = ref(""); |
| | | onMounted(() => { |
| | | const routers = JSON.parse(Cookies.get('routers')) ; |
| | | firstPage.value = routers[0].path; |
| | | if(routers[0].children){ |
| | | firstPage.value = routers[0].path + '/' + routers[0].children[0].path; |
| | | }else { |
| | | firstPage.value = routers[0].path; |
| | | } |
| | | |
| | | console.log(routers,'firstPage.value') |
| | | console.log(firstPage.value,'firstPage.value') |
| | | if(Cookies.get('configInfo')){ |
| | | const config = JSON.parse(Cookies.get('configInfo')) |
| | | if(config.logoPath != ''){ |
| | | logoImg.value = import.meta.env.VITE_APP_BASE_API + "/" + config.logoPath |
| | | }else { |
| | | logoImg.value = logo |
| | | } |
| | | }else { |
| | | logoImg.value = logo |
| | | } |
| | | |
| | | |
| | | }); |
| | | const title = import.meta.env.VITE_APP_TITLE; |
| | |
| | | |
| | | & .sidebar-logo { |
| | | width: 32px; |
| | | height: 32px; |
| | | height: auto; |
| | | vertical-align: middle; |
| | | //margin-right: 8px; |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | & .sidebar-title { |
| | |
| | | import Layout from '@/layout' |
| | | const menu = { |
| | | adminMenu: [ |
| | | { |
| | | path: '/homePage', |
| | | redirect: '/homePage', |
| | | meta: { title: '首页',icon: 'server'}, |
| | | children: [ |
| | | |
| | | { |
| | | path: 'homePage', |
| | | name: 'company', |
| | | meta: { title: '工作台',icon: 'server'} |
| | | } , |
| | | ] |
| | | }, |
| | | { |
| | | path: '/warehouseManage', |
| | | name: 'warehouseManage', |
| | | meta: { title: '入库管理',icon: 'form',affix: true } |
| | | }, |
| | | |
| | | { |
| | | path: '/electronicWarehouse', |
| | | name: 'electronicWarehouse', |
| | | meta: { title: '电子仓库',icon: 'build',affix: true } |
| | | }, |
| | | // { |
| | | // path: '/detailList', |
| | | // name: 'detailList', |
| | | // meta: { title: '危化品详单',icon: 'education',affix: true } |
| | | // path: '/homePageIndex', |
| | | // redirect: '/homePageIndex', |
| | | // meta: { title: '首页',icon: 'server'}, |
| | | // children: [ |
| | | // |
| | | // { |
| | | // path: 'homePageIndex', |
| | | // name: 'homePageIndex', |
| | | // meta: { title: '工作台',icon: 'server'} |
| | | // } , |
| | | // ] |
| | | // }, |
| | | { |
| | | path: '/accessRecords', |
| | | name: 'accessRecords', |
| | | meta: { title: '取用记录',icon: 'job',affix: true } |
| | | }, |
| | | { |
| | | path: '/traceableQuery', |
| | | name: 'traceableQuery', |
| | | meta: { title: '溯源查询',icon: 'log',affix: true } |
| | | }, |
| | | { |
| | | path: '/overdueWarning', |
| | | name: 'overdueWarning', |
| | | meta: { title: '超期预警',icon: 'peoples',affix: true } |
| | | }, |
| | | // { |
| | | // path: '/warehouseManage', |
| | | // name: 'warehouseManage', |
| | | // meta: { title: '入库管理',icon: 'form',affix: true } |
| | | // }, |
| | | // |
| | | // { |
| | | // path: '/electronicWarehouse', |
| | | // name: 'electronicWarehouse', |
| | | // meta: { title: '电子仓库',icon: 'build',affix: true } |
| | | // }, |
| | | // { |
| | | // path: '/accessRecords', |
| | | // name: 'accessRecords', |
| | | // meta: { title: '取用记录',icon: 'job',affix: true } |
| | | // }, |
| | | // { |
| | | // path: '/traceableQuery', |
| | | // name: 'traceableQuery', |
| | | // meta: { title: '溯源查询',icon: 'log',affix: true } |
| | | // }, |
| | | // { |
| | | // path: '/overdueWarning', |
| | | // name: 'overdueWarning', |
| | | // meta: { title: '超期预警',icon: 'peoples',affix: true } |
| | | // }, |
| | | { |
| | | path: '/basicInfo', |
| | | name: 'basicInfo', |
| | |
| | | redirect: '/systemManage/warehouse', |
| | | meta: { title: '系统管理',icon: 'dict'}, |
| | | children: [ |
| | | // { |
| | | // path: 'warehouse', |
| | | // name: 'warehouse', |
| | | // meta: { title: '仓库管理',icon: 'form'} |
| | | // } , |
| | | { |
| | | path: 'company', |
| | | name: 'company', |
| | | meta: { title: '企业管理',icon: 'form'} |
| | | } , |
| | | { |
| | | path: 'config', |
| | | name: 'config', |
| | | meta: { title: '企业配置',icon: 'list'} |
| | | } , |
| | | { |
| | | path: 'user', |
| | | name: 'user', |
| | | meta: { title: '用户管理',icon: 'list'} |
| | | meta: { title: '用户管理',icon: 'peoples'} |
| | | } , |
| | | // { |
| | | // path: 'department', |
| | | // name: 'department', |
| | | // meta: { title: '部门管理',icon: 'logininfor'} |
| | | // } , |
| | | ] |
| | | }, |
| | | ], |
| | | companyMenu: [ |
| | | { |
| | | path: '/homePage', |
| | | redirect: '/homePage', |
| | | path: '/homePageIndex', |
| | | redirect: '/homePageIndex', |
| | | meta: { title: '首页',icon: 'server'}, |
| | | children: [ |
| | | |
| | | { |
| | | path: 'homePage', |
| | | name: 'company', |
| | | path: 'homePageIndex', |
| | | name: 'homePageIndex', |
| | | meta: { title: '工作台',icon: 'server'} |
| | | } , |
| | | ] |
| | |
| | | ] |
| | | }, |
| | | ], |
| | | commonMenu: [ |
| | | { |
| | | path: '/homePageIndex', |
| | | redirect: '/homePageIndex', |
| | | meta: { title: '首页',icon: 'server'}, |
| | | children: [ |
| | | |
| | | { |
| | | path: 'homePageIndex', |
| | | name: 'homePageIndex', |
| | | meta: { title: '工作台',icon: 'server'} |
| | | } , |
| | | ] |
| | | }, |
| | | { |
| | | path: '/warehouseManage', |
| | | name: 'warehouseManage', |
| | | meta: { title: '入库管理',icon: 'form',affix: true } |
| | | }, |
| | | { |
| | | path: '/electronicWarehouse', |
| | | name: 'electronicWarehouse', |
| | | meta: { title: '电子仓库',icon: 'build',affix: true } |
| | | }, |
| | | // { |
| | | // path: '/detailList', |
| | | // name: 'detailList', |
| | | // meta: { title: '危化品详单',icon: 'education',affix: true } |
| | | // }, |
| | | { |
| | | path: '/accessRecords', |
| | | name: 'accessRecords', |
| | | meta: { title: '取用记录',icon: 'job',affix: true } |
| | | }, |
| | | { |
| | | path: '/traceableQuery', |
| | | name: 'traceableQuery', |
| | | meta: { title: '溯源查询',icon: 'log',affix: true } |
| | | }, |
| | | { |
| | | path: '/overdueWarning', |
| | | name: 'overdueWarning', |
| | | meta: { title: '超期预警',icon: 'peoples',affix: true } |
| | | }, |
| | | { |
| | | path: '/basicInfo', |
| | | name: 'basicInfo', |
| | | meta: { title: '危化品基础信息',icon: 'monitor',affix: true } |
| | | }, |
| | | { |
| | | path: '/finishedBasicInfo', |
| | | name: 'finishedBasicInfo', |
| | | meta: { title: '成品基础信息',icon: 'monitor',affix: true } |
| | | }, |
| | | { |
| | | path: '/systemManage', |
| | | redirect: '/systemManage/warehouse', |
| | | meta: { title: '系统管理',icon: 'dict'}, |
| | | children: [ |
| | | { |
| | | path: 'warehouse', |
| | | name: 'warehouse', |
| | | meta: { title: '仓库管理',icon: 'form'} |
| | | } , |
| | | // { |
| | | // path: 'company', |
| | | // name: 'company', |
| | | // meta: { title: '企业管理',icon: 'form'} |
| | | // } , |
| | | // { |
| | | // path: 'user', |
| | | // name: 'user', |
| | | // meta: { title: '用户管理',icon: 'list'} |
| | | // } , |
| | | // { |
| | | // path: 'department', |
| | | // name: 'department', |
| | | // meta: { title: '部门管理',icon: 'logininfor'} |
| | | // } , |
| | | ] |
| | | }, |
| | | ], |
| | | |
| | | } |
| | | export default menu; |
| | |
| | | ] |
| | | }, |
| | | { |
| | | path: '/homePage', |
| | | path: '/homePageIndex', |
| | | component: Layout, |
| | | redirect: '/homePage', |
| | | redirect: '/homePageIndex', |
| | | meta: { title: '首页'}, |
| | | children: [ |
| | | { |
| | | path: 'homePage', |
| | | path: 'homePageIndex', |
| | | component: () => import('@/views/hazardousChemicals/homePage/index.vue'), |
| | | name: 'homePage', |
| | | name: 'homePageIndex', |
| | | meta: { title: '工作台',icon: 'form'} |
| | | }, |
| | | ] |
| | |
| | | name: 'department', |
| | | meta: { title: '部门管理',icon: 'form'} |
| | | }, |
| | | { |
| | | path: 'config', |
| | | component: () => import('@/views/hazardousChemicals/systemManage/config/index.vue'), |
| | | name: 'config', |
| | | meta: { title: '企业配置',icon: 'form'} |
| | | }, |
| | | |
| | | ] |
| | | }, |
| | | |
| | |
| | | import defAva from '@/assets/images/profile.jpg' |
| | | import Cookies from "js-cookie"; |
| | | import {getUserById} from "@/api/hazardousChemicals/user"; |
| | | import {getConfigById} from "@/api/hazardousChemicals/config"; |
| | | const useUserStore = defineStore( |
| | | 'user', |
| | | { |
| | |
| | | setToken(res.data.token) |
| | | if(res.data && res.data.id){ |
| | | const info = await getUserById(res.data.id); |
| | | if(info.data.code === 200){} |
| | | Cookies.set('userInfo',JSON.stringify(info.data)) |
| | | if(info.code === 200){ |
| | | Cookies.set('userInfo',JSON.stringify(info.data)) |
| | | } |
| | | if(info.data.userType != 0){ |
| | | const con = await getConfigById(res.data.companyId); |
| | | if(con.code === 200){ |
| | | Cookies.set('configInfo',JSON.stringify(con.data)) |
| | | } |
| | | } |
| | | } |
| | | this.token = res.data.token |
| | | resolve() |
| | |
| | | if(type === 'code'){ |
| | | state.form.code = value |
| | | }else { |
| | | state.form = value |
| | | |
| | | state.form = JSON.parse(JSON.stringify(value)) |
| | | } |
| | | |
| | | await getAllFlow() |
| | |
| | | |
| | | <template> |
| | | <div class="greetings" v-loading="loading"> |
| | | <el-upload accept=".mp4, .mp3, .xls, .xlsx, .doc, .docx, .ppt, .pptx, .pdf" :on-change="handleFileChange" :on-preview="view" :auto-upload="false" ref="uploadfileComponent" :limit="1" :on-exceed="handleExceed" v-model:file-list="fileList"> |
| | | <template #trigger> |
| | | <el-button type="primary">选择文件</el-button> |
| | | </template> |
| | | <el-button :disabled="uploadDisabled" style="margin-left: 10px" type="success" @click="handlerUpload">上传</el-button> |
| | | <el-button class="ml-3" type="success" @click="resetData" >重置</el-button> |
| | | <template #tip> |
| | | <br /><br /> |
| | | <span>上传进度:{{ fakeUploadPercentage }}%</span> |
| | | <el-progress :text-inside="true" :stroke-width="26" :percentage="fakeUploadPercentage" /> |
| | | <div class="el-upload__tip text-red">限制一个文件, 新文件将会覆盖原文件</div> |
| | | </template> |
| | | </el-upload> |
| | | <br> |
| | | <div v-if="container.showVideo" style="width: 300px;height: 200px"> |
| | | <video ref="videoPlayer" class="video-js" style="margin: auto auto"></video> |
| | | </div> |
| | | <!-- <div class="greetings" v-loading="loading">--> |
| | | <!-- <el-upload accept=".mp4, .mp3, .xls, .xlsx, .doc, .docx, .ppt, .pptx, .pdf" :on-change="handleFileChange" :on-preview="view" :auto-upload="false" ref="uploadfileComponent" :limit="1" :on-exceed="handleExceed" v-model:file-list="fileList">--> |
| | | <!-- <template #trigger>--> |
| | | <!-- <el-button type="primary">选择文件</el-button>--> |
| | | <!-- </template>--> |
| | | <!-- <el-button :disabled="uploadDisabled" style="margin-left: 10px" type="success" @click="handlerUpload">上传</el-button>--> |
| | | <!-- <el-button class="ml-3" type="success" @click="resetData" >重置</el-button>--> |
| | | <!-- <template #tip>--> |
| | | <!-- <br /><br />--> |
| | | <!-- <span>上传进度:{{ fakeUploadPercentage }}%</span>--> |
| | | <!-- <el-progress :text-inside="true" :stroke-width="26" :percentage="fakeUploadPercentage" />--> |
| | | <!-- <div class="el-upload__tip text-red">限制一个文件, 新文件将会覆盖原文件</div>--> |
| | | <!-- </template>--> |
| | | <!-- </el-upload>--> |
| | | <!-- <br>--> |
| | | <!-- <div v-if="container.showVideo" style="width: 300px;height: 200px">--> |
| | | <!-- <video ref="videoPlayer" class="video-js" style="margin: auto auto"></video>--> |
| | | <!-- </div>--> |
| | | |
| | | </div> |
| | | <!-- </div>--> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessage } from "element-plus"; |
| | | import videojs from "video.js" |
| | | import { computed, nextTick, onMounted, onUnmounted,ref,reactive,watch } from "vue"; |
| | | import SparkMD5 from "spark-md5"; |
| | | import {uploadFileRequest,mergeFileRequest} from "@/api/onlineEducation/upload" |
| | | import pLimit from 'p-limit' |
| | | |
| | | const videoPlayer = ref(null) |
| | | const myPlayer = ref(null) |
| | | const uploadDisabled=ref(false) |
| | | const chunkSize = ref(10 * 1024 * 1024) // 切片大小 |
| | | const uploadedCount=ref(0) //已上传的分配个数 |
| | | const fileChunkList=ref([]) |
| | | const fileList=ref([]) |
| | | const uploadfileComponent=ref(null) |
| | | const emit = defineEmits(["getFile"]); |
| | | const loading = ref(false) |
| | | const props = defineProps({ |
| | | responseType: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }) |
| | | const container=reactive({ |
| | | file:{ |
| | | name:'', |
| | | percentage:0, |
| | | status:1, |
| | | size:0, |
| | | url:'', |
| | | raw:null, |
| | | uid:0 |
| | | }, |
| | | fileMd5:'', |
| | | worker:null, |
| | | showVideo:false |
| | | }) |
| | | // 生成文件hash的进度 |
| | | const hashPercentage = ref(0) |
| | | // 显示在页面上的文件上传进度 |
| | | const fakeUploadPercentage = ref(0) |
| | | const type = ref(); |
| | | onMounted(() => { |
| | | type.value = props.responseType |
| | | // getVideo(props.responseType) |
| | | |
| | | }) |
| | | const resourcePath = ref(); |
| | | const getVideo = (value) => { |
| | | type.value = value; |
| | | if(value == 1){ |
| | | // container.showVideo = true |
| | | nextTick(() => { |
| | | console.log("111111",videoPlayer.value) |
| | | myPlayer.value = videojs(videoPlayer.value, { |
| | | poster: "",//视频封面 |
| | | controls: true,//视频控件 |
| | | autoplay:true,//自动播放 |
| | | sources: [ |
| | | { |
| | | src: resourcePath.value ? import.meta.env.VITE_APP_RESOURCE_API + resourcePath.value : '', |
| | | // src:'', |
| | | type: 'application/x-mpegURL', |
| | | } |
| | | ], |
| | | controlBar: { |
| | | remainingTimeDisplay: { |
| | | displayNegative: false |
| | | } |
| | | }, |
| | | playbackRates: [0.5, 1, 1.5, 2]//设置播放速度 |
| | | }, onPlayerReady) |
| | | }); |
| | | } |
| | | } |
| | | // watch(() => props.responseType, value => getVideo(value)) |
| | | onUnmounted(() => { |
| | | if (myPlayer.value) { |
| | | myPlayer.value.dispose() |
| | | } |
| | | }) |
| | | |
| | | const dispose = () => { |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // resourcePath.value = '' |
| | | // } |
| | | container.showVideo = false; |
| | | resourcePath.value = '' |
| | | hashPercentage.value=0 |
| | | uploadPercentage.value=0 |
| | | fakeUploadPercentage.value=0 |
| | | uploadedCount.value=0 |
| | | fileChunkList.value=[] |
| | | fileList.value=[] |
| | | } |
| | | |
| | | const changeType = (val) => { |
| | | type.value = val |
| | | dispose() |
| | | if(val == 1){ |
| | | container.showVideo = true |
| | | nextTick(() => { |
| | | getVideo(val) |
| | | }) |
| | | } |
| | | } |
| | | const openValue = ref(); |
| | | const open = (val) => { |
| | | console.log("val",val) |
| | | openValue.value = val |
| | | fakeUploadPercentage.value = 100 |
| | | if(val.resourceType == 1){ |
| | | container.showVideo = true |
| | | resourcePath.value = val.resourcePath; |
| | | getVideo(val.resourceType) |
| | | }else { |
| | | container.showVideo = false |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | fileList.value.push({ |
| | | path: val.resourcePath, |
| | | name: val.originName |
| | | }) |
| | | } |
| | | } |
| | | const view = (file) => { |
| | | console.log('vlco',file) |
| | | // console.log("点击文件=>", file); |
| | | const url = import.meta.env.VITE_APP_RESOURCE_API + file.path; |
| | | const link = document.createElement("a"); |
| | | link.href = url; |
| | | link.download = file.name; |
| | | // link.target = "_blank"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | } |
| | | // video初始化完成的回调函数 |
| | | const onPlayerReady = () => { |
| | | myPlayer.value.log("play.....") |
| | | bindVideoEvents() |
| | | } |
| | | // 绑定事件 |
| | | const bindVideoEvents = () => { |
| | | if (!myPlayer.value) return |
| | | myPlayer.value.on('play', onPlay) |
| | | myPlayer.value.on('pause', onPause) |
| | | myPlayer.value.on('ended', onEnded) |
| | | myPlayer.value.on('timeupdate', onTimeupdate) |
| | | myPlayer.value.on('loadedmetadata', onLoadedmetadata) |
| | | myPlayer.value.on('fullscreenchange', onFullscreenchange) |
| | | myPlayer.value.on('error', err => { |
| | | console.log('视频加载发生错误', err) |
| | | }) |
| | | } |
| | | |
| | | const onPlay = () => { |
| | | console.log('播放视频') |
| | | } |
| | | const onPause = () => { |
| | | console.log('暂停播放') |
| | | } |
| | | const onEnded = () => {} |
| | | const onTimeupdate = () => { |
| | | console.log('播放位置已更改时,播放时间更新') |
| | | } |
| | | // 全屏切换 |
| | | const onFullscreenchange = () => { |
| | | console.log('全屏状态改变') |
| | | } |
| | | // 元数据加载完成 |
| | | const onLoadedmetadata = () => { |
| | | console.log('元数据加载完成') |
| | | |
| | | } |
| | | |
| | | |
| | | //计算文件上传的进度 |
| | | const uploadPercentage= computed({ |
| | | get(){ |
| | | if(!container.file||!fileChunkList.value.length){ |
| | | return 0 |
| | | } |
| | | const loaded=fileChunkList.value.map(item => item.size * item.percentage).reduce((acc,cur) => { |
| | | return acc+cur |
| | | }) |
| | | console.log('loaded',uploadedCount.value,loaded) |
| | | return parseInt((loaded/container.file.size).toFixed(2)) |
| | | }, |
| | | set(value){ |
| | | return value |
| | | } |
| | | }) |
| | | |
| | | // watch uploadPercentage,得到fakeUploadPercentage |
| | | watch(uploadPercentage, (newValue) => { |
| | | if (newValue >= fakeUploadPercentage.value) { |
| | | fakeUploadPercentage.value = newValue |
| | | } |
| | | }) |
| | | |
| | | const resetData = () => { |
| | | container.showVideo = false |
| | | resourcePath.value = '' |
| | | hashPercentage.value=0 |
| | | uploadPercentage.value=0 |
| | | fakeUploadPercentage.value=0 |
| | | uploadedCount.value=0 |
| | | fileChunkList.value=[] |
| | | fileList.value=[] |
| | | if(container.worker){ |
| | | container.worker.onmessage=null |
| | | } |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | const file = { |
| | | resourceSize: null, |
| | | md5: '', |
| | | resourcePath: '', |
| | | mediaType: '', |
| | | docPage: 0, |
| | | resourceLength: '', |
| | | originName:'' |
| | | } |
| | | emit("getFile",file) |
| | | } |
| | | |
| | | //选择了文件 |
| | | const handleFileChange=(uploadFile,uploadFiles) =>{ |
| | | // resetData() |
| | | if(!uploadFile){ |
| | | return |
| | | } |
| | | container.file=uploadFile |
| | | fileList.value=uploadFiles |
| | | } |
| | | |
| | | const handleExceed= (files) => { |
| | | uploadfileComponent.value.clearFiles() |
| | | nextTick(() => { |
| | | uploadfileComponent.value.handleStart(files[0]) |
| | | }) |
| | | } |
| | | |
| | | //上传 |
| | | const handlerUpload= async() => { |
| | | |
| | | if(type.value == null){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请先选择资源类型' |
| | | }); |
| | | return false |
| | | } |
| | | |
| | | if(!container.file.raw){ |
| | | return |
| | | } |
| | | if(container.file.raw.size > 1024 * 1024 * 1000){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件大小不能超过1G' |
| | | }); |
| | | return false |
| | | } |
| | | |
| | | const filetype = container.file.raw.name.split(".").pop(); |
| | | const extension = (filetype === "mp4" || filetype ==="mp3" || filetype ==="xls" || filetype === "xlsx" || filetype ==="doc" || filetype ==="docx" || filetype === "ppt" || filetype ==="pptx" || filetype ==="pdf"); |
| | | if (!extension ) { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '暂不支持该格式上传' |
| | | }); |
| | | return false; |
| | | } |
| | | if((type.value == 1 && filetype != 'mp4') || (type.value == 2 && filetype != 'mp3')){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传所选资源类型的文件' |
| | | }); |
| | | return false; |
| | | } |
| | | if(type.value == 3){ |
| | | if( filetype == 'xls' || filetype == 'xlsx' || filetype == 'doc'|| filetype == 'docx'|| filetype == 'ppt'|| filetype == 'pptx'|| filetype == 'pdf' ){ |
| | | |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传所选资源类型的文件' |
| | | }); |
| | | return false; |
| | | } |
| | | } |
| | | loading.value = true |
| | | //文件分片 |
| | | const chunkList=createFileChunk(container.file.raw) |
| | | console.log('文件分了多少片:',chunkList.length) |
| | | //通过webworker计算出文件hash |
| | | container.fileMd5=await calculateMd5(chunkList) |
| | | console.log('文件hash1:',container.fileMd5) |
| | | // container.fileMd5=await getFileMD5(container.file.raw) |
| | | // console.log('文件hash2:',container.hash) |
| | | |
| | | fileChunkList.value=[] |
| | | fileChunkList.value=chunkList.map(({file},index) => ({ |
| | | fileMd5:container.fileMd5, |
| | | index, |
| | | chunkName: `${container.fileMd5}-${index}`, |
| | | chunk:file, |
| | | size:file.size, |
| | | // 如果已上传切片数组uploadedList中包含这个切片,则证明这个切片之前已经上传成功了,进度设为100。 |
| | | percentage:0 |
| | | })) |
| | | |
| | | uploadChunks(fileChunkList) |
| | | |
| | | } |
| | | |
| | | //文件分片 |
| | | const createFileChunk = (file,size=chunkSize.value) => { |
| | | const chunkList=[] |
| | | let cur=0 |
| | | while(cur<file.size){ |
| | | chunkList.push({ |
| | | file:file.slice(cur,cur+size), |
| | | }) |
| | | cur+=size |
| | | } |
| | | return chunkList |
| | | } |
| | | |
| | | //计算文件md5 方法1 |
| | | const calculateMd5 = (chunkList) => { |
| | | return new Promise((resolve) => { |
| | | container.worker=new Worker('/hash.js') |
| | | container.worker.postMessage({fileChunkList:chunkList}) |
| | | container.worker.onmessage= (e) => { |
| | | const {percentage,hash} = e.data |
| | | hashPercentage.value=percentage.toFixed(2) |
| | | if(hash){ |
| | | resolve(hash) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | //计算文件md5 方法2 |
| | | const getFileMD5 = (file) => { |
| | | return new Promise((resolve, reject) => { |
| | | const spark = new SparkMD5.ArrayBuffer() |
| | | const fileReader = new FileReader() |
| | | fileReader.onload = (e) => { |
| | | spark.append(e.target?.result) |
| | | resolve(spark.end()) |
| | | } |
| | | fileReader.onerror = () => { |
| | | reject('') |
| | | } |
| | | fileReader.readAsArrayBuffer(file) |
| | | }) |
| | | } |
| | | |
| | | //计算上传进度 |
| | | const createProgressHandler = (item) => { |
| | | console.log('createProgresshandler -> item', item); |
| | | return (p) => { |
| | | if(item.percentage>=100){ |
| | | item.percentage = 100 |
| | | }else{ |
| | | item.percentage=parseInt(String((p.loaded/p.total)*100)) |
| | | } |
| | | // 确保进度百分比不会超过100% |
| | | if (item.percentage > 100) item.percentage = 100 |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | //上传切片 |
| | | const uploadChunks= async(uploadedList) => { |
| | | const limit = pLimit(10); // 控制并发数为10 |
| | | const requestList=uploadedList.value.map(({chunk,chunkName,index,fileMd5}) => { |
| | | const formdata=new FormData() |
| | | formdata.append('file',chunk) |
| | | formdata.append('chunkName',chunkName) |
| | | formdata.append('fileName',container.file.name) |
| | | formdata.append('fileMd5',fileMd5) |
| | | formdata.append('index',index) |
| | | return {formdata,index} |
| | | }).map(async ({formdata,index}) => { |
| | | return limit(() => doUploadChunk({data:formdata,onUploadProgress:createProgressHandler(fileChunkList.value[index])})) |
| | | }) |
| | | await Promise.all(requestList) |
| | | console.log("数组:",fileChunkList) |
| | | if(uploadedCount.value>=fileChunkList.value.length){ |
| | | mergeRequest() |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | const doUploadChunk = ({data,onUploadProgress}) => { |
| | | return new Promise((resolve) => { |
| | | uploadFileRequest(data,onUploadProgress).then((result) => { |
| | | let resData=result.data |
| | | if(result&&result.code==200){ |
| | | uploadedCount.value=uploadedCount.value+1 |
| | | fileChunkList.value[data.get('index')].percentage=100 //手动更新进度 |
| | | console.log(uploadedCount.value,'result--------------') |
| | | } |
| | | resolve('done') |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const mergeRequest = async() => { |
| | | if(container.file.name.lastIndexOf(".") === -1){ |
| | | ElMessage.warning("请输入文件后缀名") |
| | | return |
| | | } |
| | | let data=await mergeFileRequest({fileMd5:container.fileMd5,fileName:container.file.name}) |
| | | console.log(data,"mege------------222") |
| | | if(data && data.code==200){ |
| | | const filetype = data.data.originName.split(".").pop(); |
| | | if(filetype == 'mp4' || filetype == 'MP4'){ |
| | | container.showVideo = true |
| | | await nextTick(() => { |
| | | |
| | | console.log("myPlayer.value",myPlayer.value) |
| | | myPlayer.value.src( |
| | | { |
| | | src: import.meta.env.VITE_APP_RESOURCE_API +data.data.path, |
| | | type: 'application/x-mpegURL', |
| | | }) |
| | | // myPlayer.value.load() |
| | | myPlayer.value.play().catch((error) => { |
| | | console.error('Error playing video:', error); |
| | | }); |
| | | }) |
| | | // myPlayer.value.pause() |
| | | //myPlayer.value.reset() |
| | | } |
| | | const file = { |
| | | resourceSize: data.data.size, |
| | | md5: data.data.md5, |
| | | resourcePath: data.data.path, |
| | | mediaType: filetype, |
| | | docPage: data.data.docPage, |
| | | resourceLength: data.data.resourceLength, |
| | | originName: data.data.originName |
| | | } |
| | | emit("getFile",file) |
| | | |
| | | |
| | | loading.value = false |
| | | ElMessage.success("上传成功") |
| | | }else{ |
| | | ElMessage.success("合并数据失败") |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | dispose, |
| | | changeType, |
| | | open |
| | | }); |
| | | // import { ElMessage } from "element-plus"; |
| | | // import videojs from "video.js" |
| | | // import { computed, nextTick, onMounted, onUnmounted,ref,reactive,watch } from "vue"; |
| | | // import SparkMD5 from "spark-md5"; |
| | | // import {uploadFileRequest,mergeFileRequest} from "@/api/onlineEducation/upload" |
| | | // import pLimit from 'p-limit' |
| | | // |
| | | // const videoPlayer = ref(null) |
| | | // const myPlayer = ref(null) |
| | | // const uploadDisabled=ref(false) |
| | | // const chunkSize = ref(10 * 1024 * 1024) // 切片大小 |
| | | // const uploadedCount=ref(0) //已上传的分配个数 |
| | | // const fileChunkList=ref([]) |
| | | // const fileList=ref([]) |
| | | // const uploadfileComponent=ref(null) |
| | | // const emit = defineEmits(["getFile"]); |
| | | // const loading = ref(false) |
| | | // const props = defineProps({ |
| | | // responseType: { |
| | | // type: Number, |
| | | // default: 0 |
| | | // } |
| | | // }) |
| | | // const container=reactive({ |
| | | // file:{ |
| | | // name:'', |
| | | // percentage:0, |
| | | // status:1, |
| | | // size:0, |
| | | // url:'', |
| | | // raw:null, |
| | | // uid:0 |
| | | // }, |
| | | // fileMd5:'', |
| | | // worker:null, |
| | | // showVideo:false |
| | | // }) |
| | | // // 生成文件hash的进度 |
| | | // const hashPercentage = ref(0) |
| | | // // 显示在页面上的文件上传进度 |
| | | // const fakeUploadPercentage = ref(0) |
| | | // const type = ref(); |
| | | // onMounted(() => { |
| | | // type.value = props.responseType |
| | | // // getVideo(props.responseType) |
| | | // |
| | | // }) |
| | | // const resourcePath = ref(); |
| | | // const getVideo = (value) => { |
| | | // type.value = value; |
| | | // if(value == 1){ |
| | | // // container.showVideo = true |
| | | // nextTick(() => { |
| | | // console.log("111111",videoPlayer.value) |
| | | // myPlayer.value = videojs(videoPlayer.value, { |
| | | // poster: "",//视频封面 |
| | | // controls: true,//视频控件 |
| | | // autoplay:true,//自动播放 |
| | | // sources: [ |
| | | // { |
| | | // src: resourcePath.value ? import.meta.env.VITE_APP_RESOURCE_API + resourcePath.value : '', |
| | | // // src:'', |
| | | // type: 'application/x-mpegURL', |
| | | // } |
| | | // ], |
| | | // controlBar: { |
| | | // remainingTimeDisplay: { |
| | | // displayNegative: false |
| | | // } |
| | | // }, |
| | | // playbackRates: [0.5, 1, 1.5, 2]//设置播放速度 |
| | | // }, onPlayerReady) |
| | | // }); |
| | | // } |
| | | // } |
| | | // // watch(() => props.responseType, value => getVideo(value)) |
| | | // onUnmounted(() => { |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | // }) |
| | | // |
| | | // const dispose = () => { |
| | | // // if (myPlayer.value) { |
| | | // // myPlayer.value.dispose() |
| | | // // resourcePath.value = '' |
| | | // // } |
| | | // container.showVideo = false; |
| | | // resourcePath.value = '' |
| | | // hashPercentage.value=0 |
| | | // uploadPercentage.value=0 |
| | | // fakeUploadPercentage.value=0 |
| | | // uploadedCount.value=0 |
| | | // fileChunkList.value=[] |
| | | // fileList.value=[] |
| | | // } |
| | | // |
| | | // const changeType = (val) => { |
| | | // type.value = val |
| | | // dispose() |
| | | // if(val == 1){ |
| | | // container.showVideo = true |
| | | // nextTick(() => { |
| | | // getVideo(val) |
| | | // }) |
| | | // } |
| | | // } |
| | | // const openValue = ref(); |
| | | // const open = (val) => { |
| | | // console.log("val",val) |
| | | // openValue.value = val |
| | | // fakeUploadPercentage.value = 100 |
| | | // if(val.resourceType == 1){ |
| | | // container.showVideo = true |
| | | // resourcePath.value = val.resourcePath; |
| | | // getVideo(val.resourceType) |
| | | // }else { |
| | | // container.showVideo = false |
| | | // // if (myPlayer.value) { |
| | | // // myPlayer.value.dispose() |
| | | // // } |
| | | // fileList.value.push({ |
| | | // path: val.resourcePath, |
| | | // name: val.originName |
| | | // }) |
| | | // } |
| | | // } |
| | | // const view = (file) => { |
| | | // console.log('vlco',file) |
| | | // // console.log("点击文件=>", file); |
| | | // const url = import.meta.env.VITE_APP_RESOURCE_API + file.path; |
| | | // const link = document.createElement("a"); |
| | | // link.href = url; |
| | | // link.download = file.name; |
| | | // // link.target = "_blank"; |
| | | // document.body.appendChild(link); |
| | | // link.click(); |
| | | // document.body.removeChild(link); |
| | | // } |
| | | // // video初始化完成的回调函数 |
| | | // const onPlayerReady = () => { |
| | | // myPlayer.value.log("play.....") |
| | | // bindVideoEvents() |
| | | // } |
| | | // // 绑定事件 |
| | | // const bindVideoEvents = () => { |
| | | // if (!myPlayer.value) return |
| | | // myPlayer.value.on('play', onPlay) |
| | | // myPlayer.value.on('pause', onPause) |
| | | // myPlayer.value.on('ended', onEnded) |
| | | // myPlayer.value.on('timeupdate', onTimeupdate) |
| | | // myPlayer.value.on('loadedmetadata', onLoadedmetadata) |
| | | // myPlayer.value.on('fullscreenchange', onFullscreenchange) |
| | | // myPlayer.value.on('error', err => { |
| | | // console.log('视频加载发生错误', err) |
| | | // }) |
| | | // } |
| | | // |
| | | // const onPlay = () => { |
| | | // console.log('播放视频') |
| | | // } |
| | | // const onPause = () => { |
| | | // console.log('暂停播放') |
| | | // } |
| | | // const onEnded = () => {} |
| | | // const onTimeupdate = () => { |
| | | // console.log('播放位置已更改时,播放时间更新') |
| | | // } |
| | | // // 全屏切换 |
| | | // const onFullscreenchange = () => { |
| | | // console.log('全屏状态改变') |
| | | // } |
| | | // // 元数据加载完成 |
| | | // const onLoadedmetadata = () => { |
| | | // console.log('元数据加载完成') |
| | | // |
| | | // } |
| | | // |
| | | // |
| | | // //计算文件上传的进度 |
| | | // const uploadPercentage= computed({ |
| | | // get(){ |
| | | // if(!container.file||!fileChunkList.value.length){ |
| | | // return 0 |
| | | // } |
| | | // const loaded=fileChunkList.value.map(item => item.size * item.percentage).reduce((acc,cur) => { |
| | | // return acc+cur |
| | | // }) |
| | | // console.log('loaded',uploadedCount.value,loaded) |
| | | // return parseInt((loaded/container.file.size).toFixed(2)) |
| | | // }, |
| | | // set(value){ |
| | | // return value |
| | | // } |
| | | // }) |
| | | // |
| | | // // watch uploadPercentage,得到fakeUploadPercentage |
| | | // watch(uploadPercentage, (newValue) => { |
| | | // if (newValue >= fakeUploadPercentage.value) { |
| | | // fakeUploadPercentage.value = newValue |
| | | // } |
| | | // }) |
| | | // |
| | | // const resetData = () => { |
| | | // container.showVideo = false |
| | | // resourcePath.value = '' |
| | | // hashPercentage.value=0 |
| | | // uploadPercentage.value=0 |
| | | // fakeUploadPercentage.value=0 |
| | | // uploadedCount.value=0 |
| | | // fileChunkList.value=[] |
| | | // fileList.value=[] |
| | | // if(container.worker){ |
| | | // container.worker.onmessage=null |
| | | // } |
| | | // // if (myPlayer.value) { |
| | | // // myPlayer.value.dispose() |
| | | // // } |
| | | // const file = { |
| | | // resourceSize: null, |
| | | // md5: '', |
| | | // resourcePath: '', |
| | | // mediaType: '', |
| | | // docPage: 0, |
| | | // resourceLength: '', |
| | | // originName:'' |
| | | // } |
| | | // emit("getFile",file) |
| | | // } |
| | | // |
| | | // //选择了文件 |
| | | // const handleFileChange=(uploadFile,uploadFiles) =>{ |
| | | // // resetData() |
| | | // if(!uploadFile){ |
| | | // return |
| | | // } |
| | | // container.file=uploadFile |
| | | // fileList.value=uploadFiles |
| | | // } |
| | | // |
| | | // const handleExceed= (files) => { |
| | | // uploadfileComponent.value.clearFiles() |
| | | // nextTick(() => { |
| | | // uploadfileComponent.value.handleStart(files[0]) |
| | | // }) |
| | | // } |
| | | // |
| | | // //上传 |
| | | // const handlerUpload= async() => { |
| | | // |
| | | // if(type.value == null){ |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '请先选择资源类型' |
| | | // }); |
| | | // return false |
| | | // } |
| | | // |
| | | // if(!container.file.raw){ |
| | | // return |
| | | // } |
| | | // if(container.file.raw.size > 1024 * 1024 * 1000){ |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '文件大小不能超过1G' |
| | | // }); |
| | | // return false |
| | | // } |
| | | // |
| | | // const filetype = container.file.raw.name.split(".").pop(); |
| | | // const extension = (filetype === "mp4" || filetype ==="mp3" || filetype ==="xls" || filetype === "xlsx" || filetype ==="doc" || filetype ==="docx" || filetype === "ppt" || filetype ==="pptx" || filetype ==="pdf"); |
| | | // if (!extension ) { |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '暂不支持该格式上传' |
| | | // }); |
| | | // return false; |
| | | // } |
| | | // if((type.value == 1 && filetype != 'mp4') || (type.value == 2 && filetype != 'mp3')){ |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '请上传所选资源类型的文件' |
| | | // }); |
| | | // return false; |
| | | // } |
| | | // if(type.value == 3){ |
| | | // if( filetype == 'xls' || filetype == 'xlsx' || filetype == 'doc'|| filetype == 'docx'|| filetype == 'ppt'|| filetype == 'pptx'|| filetype == 'pdf' ){ |
| | | // |
| | | // }else { |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '请上传所选资源类型的文件' |
| | | // }); |
| | | // return false; |
| | | // } |
| | | // } |
| | | // loading.value = true |
| | | // //文件分片 |
| | | // const chunkList=createFileChunk(container.file.raw) |
| | | // console.log('文件分了多少片:',chunkList.length) |
| | | // //通过webworker计算出文件hash |
| | | // container.fileMd5=await calculateMd5(chunkList) |
| | | // console.log('文件hash1:',container.fileMd5) |
| | | // // container.fileMd5=await getFileMD5(container.file.raw) |
| | | // // console.log('文件hash2:',container.hash) |
| | | // |
| | | // fileChunkList.value=[] |
| | | // fileChunkList.value=chunkList.map(({file},index) => ({ |
| | | // fileMd5:container.fileMd5, |
| | | // index, |
| | | // chunkName: `${container.fileMd5}-${index}`, |
| | | // chunk:file, |
| | | // size:file.size, |
| | | // // 如果已上传切片数组uploadedList中包含这个切片,则证明这个切片之前已经上传成功了,进度设为100。 |
| | | // percentage:0 |
| | | // })) |
| | | // |
| | | // uploadChunks(fileChunkList) |
| | | // |
| | | // } |
| | | // |
| | | // //文件分片 |
| | | // const createFileChunk = (file,size=chunkSize.value) => { |
| | | // const chunkList=[] |
| | | // let cur=0 |
| | | // while(cur<file.size){ |
| | | // chunkList.push({ |
| | | // file:file.slice(cur,cur+size), |
| | | // }) |
| | | // cur+=size |
| | | // } |
| | | // return chunkList |
| | | // } |
| | | // |
| | | // //计算文件md5 方法1 |
| | | // const calculateMd5 = (chunkList) => { |
| | | // return new Promise((resolve) => { |
| | | // container.worker=new Worker('/hash.js') |
| | | // container.worker.postMessage({fileChunkList:chunkList}) |
| | | // container.worker.onmessage= (e) => { |
| | | // const {percentage,hash} = e.data |
| | | // hashPercentage.value=percentage.toFixed(2) |
| | | // if(hash){ |
| | | // resolve(hash) |
| | | // } |
| | | // } |
| | | // }) |
| | | // } |
| | | // |
| | | // //计算文件md5 方法2 |
| | | // const getFileMD5 = (file) => { |
| | | // return new Promise((resolve, reject) => { |
| | | // const spark = new SparkMD5.ArrayBuffer() |
| | | // const fileReader = new FileReader() |
| | | // fileReader.onload = (e) => { |
| | | // spark.append(e.target?.result) |
| | | // resolve(spark.end()) |
| | | // } |
| | | // fileReader.onerror = () => { |
| | | // reject('') |
| | | // } |
| | | // fileReader.readAsArrayBuffer(file) |
| | | // }) |
| | | // } |
| | | // |
| | | // //计算上传进度 |
| | | // const createProgressHandler = (item) => { |
| | | // console.log('createProgresshandler -> item', item); |
| | | // return (p) => { |
| | | // if(item.percentage>=100){ |
| | | // item.percentage = 100 |
| | | // }else{ |
| | | // item.percentage=parseInt(String((p.loaded/p.total)*100)) |
| | | // } |
| | | // // 确保进度百分比不会超过100% |
| | | // if (item.percentage > 100) item.percentage = 100 |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // |
| | | // //上传切片 |
| | | // const uploadChunks= async(uploadedList) => { |
| | | // const limit = pLimit(10); // 控制并发数为10 |
| | | // const requestList=uploadedList.value.map(({chunk,chunkName,index,fileMd5}) => { |
| | | // const formdata=new FormData() |
| | | // formdata.append('file',chunk) |
| | | // formdata.append('chunkName',chunkName) |
| | | // formdata.append('fileName',container.file.name) |
| | | // formdata.append('fileMd5',fileMd5) |
| | | // formdata.append('index',index) |
| | | // return {formdata,index} |
| | | // }).map(async ({formdata,index}) => { |
| | | // return limit(() => doUploadChunk({data:formdata,onUploadProgress:createProgressHandler(fileChunkList.value[index])})) |
| | | // }) |
| | | // await Promise.all(requestList) |
| | | // console.log("数组:",fileChunkList) |
| | | // if(uploadedCount.value>=fileChunkList.value.length){ |
| | | // mergeRequest() |
| | | // } |
| | | // |
| | | // } |
| | | // |
| | | // |
| | | // const doUploadChunk = ({data,onUploadProgress}) => { |
| | | // return new Promise((resolve) => { |
| | | // uploadFileRequest(data,onUploadProgress).then((result) => { |
| | | // let resData=result.data |
| | | // if(result&&result.code==200){ |
| | | // uploadedCount.value=uploadedCount.value+1 |
| | | // fileChunkList.value[data.get('index')].percentage=100 //手动更新进度 |
| | | // console.log(uploadedCount.value,'result--------------') |
| | | // } |
| | | // resolve('done') |
| | | // }) |
| | | // }) |
| | | // } |
| | | // |
| | | // const mergeRequest = async() => { |
| | | // if(container.file.name.lastIndexOf(".") === -1){ |
| | | // ElMessage.warning("请输入文件后缀名") |
| | | // return |
| | | // } |
| | | // let data=await mergeFileRequest({fileMd5:container.fileMd5,fileName:container.file.name}) |
| | | // console.log(data,"mege------------222") |
| | | // if(data && data.code==200){ |
| | | // const filetype = data.data.originName.split(".").pop(); |
| | | // if(filetype == 'mp4' || filetype == 'MP4'){ |
| | | // container.showVideo = true |
| | | // await nextTick(() => { |
| | | // |
| | | // console.log("myPlayer.value",myPlayer.value) |
| | | // myPlayer.value.src( |
| | | // { |
| | | // src: import.meta.env.VITE_APP_RESOURCE_API +data.data.path, |
| | | // type: 'application/x-mpegURL', |
| | | // }) |
| | | // // myPlayer.value.load() |
| | | // myPlayer.value.play().catch((error) => { |
| | | // console.error('Error playing video:', error); |
| | | // }); |
| | | // }) |
| | | // // myPlayer.value.pause() |
| | | // //myPlayer.value.reset() |
| | | // } |
| | | // const file = { |
| | | // resourceSize: data.data.size, |
| | | // md5: data.data.md5, |
| | | // resourcePath: data.data.path, |
| | | // mediaType: filetype, |
| | | // docPage: data.data.docPage, |
| | | // resourceLength: data.data.resourceLength, |
| | | // originName: data.data.originName |
| | | // } |
| | | // emit("getFile",file) |
| | | // |
| | | // |
| | | // loading.value = false |
| | | // ElMessage.success("上传成功") |
| | | // }else{ |
| | | // ElMessage.success("合并数据失败") |
| | | // } |
| | | // } |
| | | // |
| | | // defineExpose({ |
| | | // dispose, |
| | | // changeType, |
| | | // open |
| | | // }); |
| | | </script> |
| | | |
| | | |
| | | <style scoped> |
| | | .greetings{ |
| | | :deep(.video-js) { |
| | | width: 300px; |
| | | height: 200px; |
| | | } |
| | | :deep(.el-icon--close) { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | h1 { |
| | | font-weight: 500; |
| | | font-size: 2.6rem; |
| | | position: relative; |
| | | top: -10px; |
| | | } |
| | | |
| | | h3 { |
| | | font-size: 1.2rem; |
| | | } |
| | | |
| | | .greetings h1, |
| | | .greetings h3 { |
| | | text-align: center; |
| | | } |
| | | |
| | | @media (min-width: 1024px) { |
| | | .greetings h1, |
| | | .greetings h3 { |
| | | text-align: left; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <el-table-column label="二维码识别号" prop="code" align="center" /> |
| | | <el-table-column label="类型" prop="productBasic.productSn" align="center" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.state === 0 ? '入库' :scope.row.state === 3 ? '标签作废' :scope.row.state === 4 ? '销售' : ''}}</span> |
| | | <span>{{scope.row.state === 0 ? '入库' :scope.row.state === 1 ? '取用' :scope.row.state === 2 ? '归还' : scope.row.state === 3? '标签作废':scope.row.state === 4 ? '用尽登记':scope.row.state === 5? '销售': ''}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数量" prop="num" align="center" width="120" > |
| | |
| | | |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="600px" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | |
| | | <el-table-column label="二维码识别号" prop="code" align="center" /> |
| | | <el-table-column label="类型" prop="hazmatBasic.productSn" align="center" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.state === 0 ? '入库' :scope.row.state === 1 ? '取用' :scope.row.state === 2 ? '归还' : scope.row.state === 3? '标签作废':''}}</span> |
| | | <span>{{scope.row.state === 0 ? '入库' :scope.row.state === 1 ? '取用' :scope.row.state === 2 ? '归还' : scope.row.state === 3? '标签作废':scope.row.state === 4 ? '用尽登记':scope.row.state === 5? '销售': ''}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数量" prop="num" align="center" width="120" > |
| | |
| | | /> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="600px" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | |
| | | import {onMounted, reactive, ref} from "vue"; |
| | | import proTable from './components/productTable.vue' |
| | | import rawTable from './components/rawTable.vue' |
| | | import Cookies from "js-cookie"; |
| | | const showFinishPro = ref(false) |
| | | const proRef = ref() |
| | | const rawRef = ref() |
| | |
| | | }) |
| | | |
| | | onMounted(()=>{ |
| | | showFinishPro.value = true; |
| | | if(Cookies.get('configInfo')){ |
| | | const config = JSON.parse(Cookies.get('configInfo')) |
| | | showFinishPro.value = config.useProd === 1; |
| | | }else { |
| | | showFinishPro.value = true |
| | | } |
| | | // data.activeName = showFinishPro.value ? 'finishPro' : 'rawMaterial' |
| | | }) |
| | | const clickTab = (tab,event) =>{ |
| | |
| | | t.value = type |
| | | title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; |
| | | if(type === 'edit' || type === 'distribute') { |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | state.characterList = state.form.hazmatCharacter.split(',') |
| | | startUsername.value = value.productSn |
| | | } |
| | |
| | | <viewQRcode ref="dialogRef" @getList="getList"></viewQRcode> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="600px" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | |
| | | |
| | | const openDialog = async (value) => { |
| | | title.value = value.productBasic.name + ' ' + '(编号:' + value.productBasic.productSn + ')' + ' '+ '的取用记录' |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | await getRecord() |
| | | dialogVisible.value = true; |
| | | } |
| | |
| | | <viewQRcode ref="dialogRef" @getList="getList"></viewQRcode> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="600px" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | |
| | | |
| | | const openDialog = async (value) => { |
| | | title.value = value.hazmatBasic.name + ' ' + '(编号:' + value.hazmatBasic.productSn + ')' + ' '+ '的取用记录' |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | await getRecord() |
| | | dialogVisible.value = true; |
| | | } |
| | |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <div style="display: flex;flex-direction: column;align-items: flex-end"> |
| | | <el-button type="primary" style="margin-bottom: 5px" @click="printCode">打印</el-button> |
| | | </div> |
| | | <el-card style="max-width: 480px"> |
| | | <div style="display: flex;flex-direction: column;align-items: center;font-size: 20px;font-weight: 600"> |
| | | <span>{{title}}</span> |
| | | <vue-qr :size="150" :margin="0" :auto-color="true" :dot-scale="1" :text="state.form.code" style="margin: 10px 0 10px 0"></vue-qr> |
| | | <span>{{state.form.code}}</span> |
| | | <div :id="state.form.code"> |
| | | <div style="display: flex;flex-direction: column;align-items: center;font-size: 16px;"> |
| | | <span>{{title}}</span> |
| | | <vue-qr :size="85" :margin="0" :auto-color="true" :dot-scale="1" :text="state.form.code" style="margin: 10px 0 10px 0"></vue-qr> |
| | | <span>{{state.form.code}}</span> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-dialog> |
| | |
| | | title.value = value.hazmatBasic.name + ' ' + '—' + ' '+ value.hazmatBasic.productSn |
| | | } |
| | | |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | dialogVisible.value = true; |
| | | } |
| | | const handleClose = () => { |
| | | dialogVisible.value = false; |
| | | emit("getList") |
| | | } |
| | | const printCode = () => { |
| | | let data = [] |
| | | data = [state.form] |
| | | let qrCodes='' |
| | | for(let index in data){ |
| | | console.log(index,'index') |
| | | qrCodes+=`<div class="my-list-col"><div class="centered-content">${document.getElementById(data[index].code).innerHTML}</div></div>` |
| | | } |
| | | const printContent=document.createElement('div') |
| | | printContent.innerHTML=qrCodes |
| | | |
| | | //创建一个新的隐藏的iframe元素 |
| | | const printFrame =document.createElement('iframe') |
| | | printFrame.style.display='none' |
| | | document.body.appendChild(printFrame) |
| | | |
| | | const printDocument=printFrame.contentWindow.document |
| | | printDocument.open() |
| | | printDocument.write(` |
| | | <html> |
| | | <head> |
| | | <title>Print</title> |
| | | <style> |
| | | @media print { |
| | | .page-break { page-break-after:always;} /* 定义分页符格式*/ |
| | | .centered-content { text-align:center;} /* 居中对齐内容*/ |
| | | @page { size:50mm 40mm;margin:0mm; } |
| | | } |
| | | </style> |
| | | </head> |
| | | <body style='margin:0;padding:0;'>${printContent.innerHTML}</body> |
| | | </html> |
| | | `) |
| | | printDocument.close() |
| | | //在打印窗口中调用打印功能 |
| | | console.log('printFrame.contentWindow.document.body.style',printFrame.contentWindow.document.body.style) |
| | | printFrame.contentWindow.print() |
| | | //移除隐藏的iframe元素 |
| | | document.body.removeChild(printFrame) |
| | | // handleClose() |
| | | } |
| | | |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | |
| | | }) |
| | | |
| | | onMounted(()=>{ |
| | | showFinishPro.value = true; |
| | | if(Cookies.get('configInfo')){ |
| | | const config = JSON.parse(Cookies.get('configInfo')) |
| | | showFinishPro.value = config.useProd === 1; |
| | | }else { |
| | | showFinishPro.value = true |
| | | } |
| | | if(Cookies.get('type')){ |
| | | data.activeName = showFinishPro.value && Cookies.get('type') ==='pro' ? 'finishPro' : 'rawMaterial' |
| | | }else{ |
| | |
| | | t.value = type |
| | | title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; |
| | | if(type === 'edit' || type === 'distribute') { |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | state.characterList = state.form.productCharacter.split(',') |
| | | startUsername.value = value.productSn |
| | | } |
| | |
| | | description: `${item.createName} 领用了 ${item.hazmatBasic.name} 状态:${item.state ==0?'未处理':'已处理' }` |
| | | } |
| | | }) |
| | | data.warningData = data.warningData.filter(item => item.state === 0) |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | |
| | | |
| | | title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '分配课时' ; |
| | | if(type === 'edit' || type === 'distribute') { |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | startUsername.value = value.username |
| | | startPhone.value = value.phone |
| | | } |
对比新文件 |
| | |
| | | <template> |
| | | <div class="notice"> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="title" |
| | | width="500px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > |
| | | <el-form-item label="公司:" prop="companyName" > |
| | | <el-select |
| | | clearable |
| | | v-model="state.form.companyName" |
| | | filterable |
| | | remote |
| | | @change="selectValue" |
| | | reserve-keyword |
| | | placeholder="请输入企业名称" |
| | | remote-show-suffix |
| | | :remote-method="getCompanyList" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in state.companyList" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.name" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="是否使用成品:" prop="useProd" > |
| | | <el-radio-group v-model="state.form.useProd"> |
| | | <el-radio :label="0">不使用</el-radio> |
| | | <el-radio :label="1">使用</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="logo:" prop="logoPath" > |
| | | <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.imgLimit' v-model:file-list="state.imgList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > |
| | | <el-icon><Plus /></el-icon> |
| | | <template #tip> |
| | | <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张,建议宽度30px左右。</div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="handleClose" size="default">取 消</el-button> |
| | | <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import {reactive, ref, toRefs} from 'vue' |
| | | import {ElMessage} from "element-plus"; |
| | | import {addWarehouse, checkName, editWarehouse} from "@/api/hazardousChemicals/warehouse"; |
| | | import {verifyPhone} from "@/utils/validate"; |
| | | import {checkBasicName} from "@/api/hazardousChemicals/basicInfo"; |
| | | import {addConfig, editConfig} from "@/api/hazardousChemicals/config"; |
| | | import {getCompany} from "@/api/hazardousChemicals/company"; |
| | | import {getToken} from "@/utils/auth"; |
| | | import {delPic} from "@/api/hazardousChemicals/config"; |
| | | |
| | | const dialogVisible = ref(false); |
| | | const title = ref(""); |
| | | const busRef = ref(); |
| | | const length = ref() |
| | | const emit = defineEmits(["getList"]); |
| | | const state = reactive({ |
| | | form: { |
| | | id: '', |
| | | companyId: null, |
| | | companyName: '', |
| | | logoPath: '', |
| | | useProd: 0 |
| | | |
| | | }, |
| | | companyList: [], |
| | | formRules:{ |
| | | companyName: [{ required: true, message: '请选择企业', trigger: 'blur' }], |
| | | useProd: [{ required: true, message: '请选择是否使用成品', trigger: 'blur' }], |
| | | }, |
| | | uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', |
| | | header: { |
| | | Authorization:getToken() |
| | | }, |
| | | imgList: [], |
| | | imgLimit: 1, |
| | | }) |
| | | |
| | | |
| | | const openDialog = async (type, value) => { |
| | | await getCompanyList("") |
| | | title.value = type === 'add' ? '新增配置' : type ==='edit' ? '编辑配置':'' ; |
| | | if(type === 'edit' ) { |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | if(value.logoPath) { |
| | | const obj = { |
| | | url: import.meta.env.VITE_APP_BASE_API + "/" + value.logoPath, |
| | | name: '' |
| | | } |
| | | state.imgList = [obj] |
| | | } |
| | | } |
| | | dialogVisible.value = true; |
| | | } |
| | | |
| | | const onSubmit = async () => { |
| | | const valid = await busRef.value.validate(); |
| | | if(valid){ |
| | | if(title.value === '新增配置'){ |
| | | const {id, ...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await addConfig(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '新增成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | }else if(title.value === '编辑配置'){ |
| | | const {...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await editConfig(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '编辑成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | const selectValue = (val) => { |
| | | state.companyList.forEach(item => { |
| | | if(item.name === val){ |
| | | state.form.companyId = item.id |
| | | } |
| | | }) |
| | | } |
| | | const getCompanyList = async (val)=>{ |
| | | if(val != ""){ |
| | | const queryParams = { |
| | | name: val |
| | | } |
| | | const res = await getCompany(queryParams) |
| | | if (res.code == 200) { |
| | | state.companyList = res.data.list |
| | | |
| | | } else { |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else { |
| | | |
| | | const queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10 |
| | | } |
| | | const res = await getCompany(queryParams) |
| | | if (res.code == 200) { |
| | | state.companyList = res.data.list |
| | | |
| | | } else { |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | } |
| | | const handleClose = () => { |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | emit("getList") |
| | | } |
| | | |
| | | const showTip =()=>{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '超出文件上传数量' |
| | | }); |
| | | } |
| | | const picSize = async (rawFile) => { |
| | | if(rawFile.size / 1024 / 1024 > 5){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件大小不能超过5M' |
| | | }); |
| | | return false |
| | | } |
| | | }; |
| | | const handleAvatarSuccess = (res, uploadFile) => { |
| | | if(res.code == 200){ |
| | | state.form.logoPath = res.data.path |
| | | }else{ |
| | | state.imgList = [] |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件上传失败' |
| | | }) |
| | | } |
| | | } |
| | | const handleRemove = async (file, uploadFiles) => { |
| | | let path = state.form.logoPath; |
| | | await delPic({path: path}).then(res => { |
| | | if(res.code == 200){ |
| | | // ElMessage({ |
| | | // type: 'success', |
| | | // message: '文件已删除' |
| | | // }) |
| | | state.form.logoPath = '' |
| | | }else{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.message |
| | | }) |
| | | } |
| | | }).catch(() => { |
| | | state.form.logoPath = '' |
| | | }); |
| | | } |
| | | const reset = () => { |
| | | state.form = { |
| | | id: '', |
| | | name: '', |
| | | remark: '', |
| | | } |
| | | } |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .notice{ |
| | | :deep(.el-form .el-form-item__label) { |
| | | font-size: 15px; |
| | | } |
| | | .file { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div style="display: flex;justify-content: space-between"> |
| | | <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > |
| | | <el-form-item> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="openDialog('add',{})" |
| | | >新增</el-button> |
| | | </el-form-item> |
| | | <el-form-item label="公司名称:" > |
| | | <el-input v-model="data.queryParams.name" placeholder="请输入公司名称"></el-input> |
| | | </el-form-item> |
| | | <el-form-item > |
| | | <el-button |
| | | type="primary" |
| | | @click="getList" |
| | | >查询</el-button> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | @click="reset" |
| | | >重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <!-- 表格数据 --> |
| | | <el-table v-loading="loading" :data="dataList" :border="true"> |
| | | <el-table-column label="序号" type="index" align="center" width="80" /> |
| | | <el-table-column label="公司名称" prop="companyName" align="center" /> |
| | | <el-table-column label="Logo" prop="remark" align="center" width="150"> |
| | | <template #default="scope"> |
| | | <div class="demo-image__preview" v-if="scope.row.imgUrl && scope.row.imgUrl.length>0"> |
| | | <el-image |
| | | style="width: auto; height: auto" |
| | | :src= "scope.row.imgUrl[0]" |
| | | :zoom-rate="1.2" |
| | | :max-scale="7" |
| | | :min-scale="0.2" |
| | | :preview-src-list="scope.row.imgUrl" |
| | | :initial-index="0" |
| | | fit="cover" |
| | | :preview-teleported=true |
| | | /> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="是否使用成品" prop="useProd" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{scope.row.useProd == 0 ? '不使用' : '使用' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" > |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <con-dialog ref="dialogRef" @getList="getList"></con-dialog> |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import conDialog from './components/configDialog.vue' |
| | | import {delWarehouse, getWarehouse} from "@/api/hazardousChemicals/warehouse"; |
| | | import {delConfig, getConfig} from "@/api/hazardousChemicals/config"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const loading = ref(false); |
| | | const dialogRef = ref(); |
| | | const data = reactive({ |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: '' |
| | | }, |
| | | total: 0, |
| | | dataList: [] |
| | | }); |
| | | |
| | | const { queryParams, total, dataList } = toRefs(data); |
| | | const classHourRef = ref(); |
| | | onMounted(()=>{ |
| | | getList() |
| | | }) |
| | | |
| | | onUnmounted(()=>{ |
| | | |
| | | }) |
| | | |
| | | const getList = async () => { |
| | | loading.value = true |
| | | const res = await getConfig(data.queryParams) |
| | | if(res.code == 200){ |
| | | data.dataList = res.data.list.map(item => { |
| | | return { |
| | | ...item, |
| | | imgUrl: item.logoPath ?[import.meta.env.VITE_APP_BASE_API + "/" + item.logoPath] : [] |
| | | } |
| | | }) |
| | | data.total = res.data.total |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | loading.value = false |
| | | } |
| | | |
| | | const openDialog = (type, value) => { |
| | | dialogRef.value.openDialog(type, value); |
| | | } |
| | | |
| | | /** 重置新增的表单以及其他数据 */ |
| | | function reset() { |
| | | data.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: '' |
| | | } |
| | | getList() |
| | | } |
| | | const handleDelete = (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定删除此条数据?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await delConfig(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('数据删除成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | |
| | | </script> |
| | |
| | | title.value = type === 'addFirst' || type === 'add' ? '新增部门' : type ==='edit' ? '编辑部门' : '' ; |
| | | if(type === 'edit') { |
| | | state.isFirst = true; |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | state.form.status = value.status == 0; |
| | | state.form.sort = value.sort; |
| | | state.form.parentId = value.parentId; |
| | |
| | | |
| | | title.value = type === 'add' ? '新增仓库' : type ==='edit' ? '编辑仓库':'' ; |
| | | if(type === 'edit' ) { |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | startUsername.value = value.username |
| | | } |
| | | dialogVisible.value = true; |
| | |
| | | const openDialog = async (type, value) => { |
| | | await getProBasic("") |
| | | await getWareHouseList("") |
| | | state.form.batchNo = moment(new Date()).format("YYYY-MM-DD") |
| | | state.form.batchNo = moment(new Date()).format("YYYYMMDD") |
| | | title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑':'' ; |
| | | if(type === 'edit' ) { |
| | | state.form = value; |
| | |
| | | const openDialog = async (type, value) => { |
| | | await getRawBasicList("") |
| | | await getWareHouseList("") |
| | | state.form.batchNo = moment(new Date()).format("YYYY-MM-DD") |
| | | state.form.batchNo = moment(new Date()).format("YYYYMMDD") |
| | | title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑':'' ; |
| | | if(type === 'edit' ) { |
| | | state.form = value; |
| | | state.form = JSON.parse(JSON.stringify(value)); |
| | | state.form.basicName = value.hazmatBasic.name |
| | | state.form.warehouseName = value.warehouse.name; |
| | | choosePro.value = value.hazmatBasic |
| | |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="title == 'pro' ? '成品二维码打印' : '危化品二维码打印'" |
| | | width="600px" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | |
| | | import {addWarehouse, checkName, editWarehouse} from "@/api/hazardousChemicals/warehouse"; |
| | | import {verifyPhone} from "@/utils/validate"; |
| | | import {checkBasicName} from "@/api/hazardousChemicals/basicInfo"; |
| | | import {getProDetail, getProductRecord} from "@/api/hazardousChemicals/productRecord"; |
| | | import {getRawDetail} from "@/api/hazardousChemicals/rawRecord"; |
| | | import {getProDetail, getProductRecord, getWhProDetail} from "@/api/hazardousChemicals/productRecord"; |
| | | import {getRawDetail, getWhRawDetail} from "@/api/hazardousChemicals/rawRecord"; |
| | | |
| | | const dialogVisible = ref(false); |
| | | const title = ref(""); |
| | |
| | | queryParams:{ |
| | | pageNum: 1, |
| | | pageSize: 5, |
| | | warehouseId: null, |
| | | basicId: null, |
| | | // warehouseId: null, |
| | | // basicId: null, |
| | | entryId: null, |
| | | code: '' |
| | | }, |
| | | chooseList: [] |
| | |
| | | |
| | | const originalList = ref([]) |
| | | const openDialog = async (type,value) => { |
| | | state.queryParams.warehouseId =value.warehouseId |
| | | state.queryParams.basicId =value.basicId |
| | | // state.queryParams.warehouseId =value.warehouseId |
| | | // state.queryParams.basicId =value.basicId |
| | | state.queryParams.entryId = value.id |
| | | title.value = type; |
| | | await getList() |
| | | |
| | |
| | | state.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 5, |
| | | warehouseId: null, |
| | | basicId: null, |
| | | entryId: null, |
| | | code: '' |
| | | } |
| | | state.total = 0 |
| | |
| | | } |
| | | const getList = async () => { |
| | | if(title.value == 'pro'){ |
| | | const res = await getProDetail(state.queryParams) |
| | | const res = await getWhProDetail(state.queryParams) |
| | | if(res.code == 200){ |
| | | state.dataList = res.data.list.map(item => { |
| | | return{ |
| | |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else { |
| | | const res = await getRawDetail(state.queryParams) |
| | | const res = await getWhRawDetail(state.queryParams) |
| | | if(res.code == 200){ |
| | | state.dataList = res.data.list.map(item => { |
| | | return{ |
| | |
| | | } |
| | | const printContent=document.createElement('div') |
| | | printContent.innerHTML=qrCodes |
| | | |
| | | //创建一个新的隐藏的iframe元素 |
| | | const printFrame =document.createElement('iframe') |
| | | printFrame.style.display='none' |
| | |
| | | `) |
| | | printDocument.close() |
| | | //在打印窗口中调用打印功能 |
| | | console.log('printFrame.contentWindow.document.body.style',printFrame.contentWindow.document.body.style) |
| | | printFrame.contentWindow.print() |
| | | //移除隐藏的iframe元素 |
| | | document.body.removeChild(printFrame) |
| | |
| | | <el-table-column label="所在仓库" prop="warehouseName" align="center" /> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" > |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="viewFlow(scope.row)">取用记录</el-button> |
| | | <el-button link type="danger" v-if="scope.row.state === 0" @click="disCard(scope.row)">标签作废</el-button> |
| | | <el-button link type="primary" @click="viewQR(scope.row)">查看二维码</el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | @pagination="getList" |
| | | /> |
| | | <viewQRcode ref="dialogRef" @getList="getList"></viewQRcode> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <flow-deail ref="flowRef"></flow-deail> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {nextTick, onMounted, reactive, ref} from "vue"; |
| | | import flowDeail from '../../../components/flowDetail.vue' |
| | | import {useRoute, useRouter} from "vue-router"; |
| | | import { |
| | | disCardPro, |
| | | getWhProDetail |
| | | } from "@/api/hazardousChemicals/productRecord"; |
| | | import viewQRcode from '@/views/hazardousChemicals/electronicWarehouse/components/viewQR.vue' |
| | |
| | | const handleClose = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | const viewFlow = (val) => { |
| | | dialogVisible.value = true |
| | | nextTick(() => { |
| | | |
| | | flowRef.value.openDialog('pro',val) |
| | | }) |
| | | |
| | | } |
| | | const disCard = async (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定作废该标签?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await disCardPro(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('操作成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | |
| | | |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | <el-table-column label="所在仓库" prop="warehouseName" align="center" /> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" > |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="viewFlow(scope.row)">取用记录</el-button> |
| | | <el-button link type="danger" v-if="scope.row.state === 0 || scope.row.state === 1|| scope.row.state === 2" @click="disCard(scope.row)">标签作废</el-button> |
| | | <el-button link type="primary" @click="viewQR(scope.row)">查看二维码</el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | @pagination="getList" |
| | | /> |
| | | <viewQRcode ref="dialogRef" @getList="getList"></viewQRcode> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="650px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <flow-deail ref="flowRef"></flow-deail> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {nextTick, onMounted, reactive, ref} from "vue"; |
| | | import {useRoute, useRouter} from "vue-router"; |
| | | import flowDeail from '../../../components/flowDetail.vue' |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {disCardRaw, getRawDetail, getWhRawDetail} from "@/api/hazardousChemicals/rawRecord"; |
| | | import viewQRcode from '@/views/hazardousChemicals/electronicWarehouse/components/viewQR.vue' |
| | |
| | | const handleClose = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | const disCard = async (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定作废该标签?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await disCardRaw(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('操作成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | |
| | | |
| | | } |
| | | const viewFlow = (val) => { |
| | | dialogVisible.value = true |
| | | nextTick(() => { |
| | | flowRef.value.openDialog('raw',val) |
| | | }) |
| | | } |
| | | |
| | | </script> |
| | | |
| | |
| | | }) |
| | | |
| | | onMounted(()=>{ |
| | | showFinishPro.value = true; |
| | | if(Cookies.get('configInfo')){ |
| | | const config = JSON.parse(Cookies.get('configInfo')) |
| | | showFinishPro.value = config.useProd === 1; |
| | | }else { |
| | | showFinishPro.value = true |
| | | } |
| | | if(Cookies.get('typeWh')){ |
| | | data.activeName = showFinishPro.value && Cookies.get('typeWh') ==='pro' ? 'finishPro' : 'rawMaterial' |
| | | }else{ |
| | |
| | | <div class="title"> |
| | | <div class="logo"> |
| | | <img class="pics2" :src="logoPng"> |
| | | <span style="font-size: 40px;color: black">沙湾市安全培训</span> |
| | | <span style="font-size: 40px;color: black"></span> |
| | | <div style="width: 2px;height: 40px;background-color: #1C68A7;margin-top: 5px;margin-left: 15px;margin-right: 15px"></div> |
| | | <span style="font-size: 28px;color: white">危化品全生命周期管理系统</span> |
| | | </div> |
| | | <div class="content"> |
| | | <div class="imgBox"> |
| | | <div class="imG"></div> |
| | | <div class="imG"> |
| | | <img style="width: auto;height: 420px" :src="back"> |
| | | </div> |
| | | </div> |
| | | <div class="formBox"> |
| | | <div class="loginTitle">账号登录</div> |
| | |
| | | import menu from "@/layout/components/Sidebar/menu"; |
| | | import dataPng from "@/assets/images/login-data.png" |
| | | import searchPng from "@/assets/images/login-search.png" |
| | | import logoPng from "@/assets/logo/logo3.png" |
| | | import logoPng from "@/assets/logo/logo1.png" |
| | | import back from "@/assets/images/logo22.png" |
| | | |
| | | const userStore = useUserStore() |
| | | const route = useRoute(); |
| | |
| | | // Cookies.set('routers',JSON.stringify(sidebarRouters.value)) |
| | | // } |
| | | const userInfo = JSON.parse(Cookies.get('userInfo')) |
| | | |
| | | if(userInfo.userType === 0) { |
| | | sidebarRouters.value = menu.adminMenu |
| | | Cookies.set('routers',JSON.stringify(sidebarRouters.value)) |
| | | }else { |
| | | sidebarRouters.value = menu.companyMenu |
| | | }else if(userInfo.userType === 1){ |
| | | const config = JSON.parse(Cookies.get('configInfo')) |
| | | if(config.useProd === 0){ |
| | | sidebarRouters.value = menu.companyMenu.filter(item => item.path != '/finishedBasicInfo') |
| | | }else { |
| | | sidebarRouters.value = menu.companyMenu |
| | | } |
| | | Cookies.set('routers',JSON.stringify(sidebarRouters.value)) |
| | | }else if(userInfo.userType === 2){ |
| | | const config = JSON.parse(Cookies.get('configInfo')) |
| | | if(config.useProd === 0){ |
| | | sidebarRouters.value = menu.commonMenu.filter(item => item.path != '/finishedBasicInfo') |
| | | }else { |
| | | sidebarRouters.value = menu.commonMenu |
| | | } |
| | | Cookies.set('routers',JSON.stringify(sidebarRouters.value)) |
| | | } |
| | | let path = "" |
| | |
| | | margin: 25px 0; |
| | | } |
| | | .imG{ |
| | | width: 500px; |
| | | height: 500px; |
| | | background-image: url(../assets/images/ad.png) ; |
| | | //width: 500px; |
| | | //height: 500px; |
| | | //background-image: url(../assets/images/logo11.jpg) ; |
| | | background-repeat: no-repeat; |
| | | position: absolute; |
| | | left: 30px; |
| | | left: -30px; |
| | | top: 30px; |
| | | } |
| | | .formBox{ |