Merge remote-tracking branch 'origin/master'
| | |
| | | <template> |
| | | <div class="content"> |
| | | <div class="header"> |
| | | <div class="header-item" style="font-size: 20px;">豆米科技</div> |
| | | <div class="header-item" style="font-size: 20px;"> |
| | | <el-dropdown trigger="click"> |
| | | <div class="eare-title"> |
| | | {{ tempCom.name}} |
| | | <div class="right-icon"> |
| | | <img src="@/assets/img/ar_drop@2x.png" alt=""> |
| | | </div> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item v-for="(item, index) in comList" :key="index" @click="selectCom(item, index)">{{item.name}}</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | |
| | | </div> |
| | | <div class="title">DM云工厂车间大屏</div> |
| | | <div class="header-item">天气</div> |
| | | <div class="header-item right"> |
| | | |
| | | <img v-if="!isFull" src="@/assets/img/ic_fullscreen@2x.png" class="full-ic" @click="fullChange"> |
| | | <img v-else src="@/assets/img/ic_exitfullscreen@2x.png" class="full-ic" @click="fullChange"> |
| | | <img src="@/assets/img/title_line@2x.png" class="right-line" alt=""> |
| | | <div class="date"> |
| | | <div class="time">{{ tempDate.time }}</div> |
| | | <div class="day">{{ `${tempDate.date} ${tempDate.day}` }}</div> |
| | | </div> |
| | | <img src="@/assets/img/title_line@2x.png" class="right-line" alt=""> |
| | | </div> |
| | | </div> |
| | | <!-- 'background': `url(${getAssets(item.bgImg)})`, --> |
| | | <div class="num-list"> |
| | | <div |
| | | v-for="(item, index) in layoutList" |
| | | :key="index" |
| | | class="num-item" |
| | | :style="{ 'background-image': `url(${getAssets(item.bgImg)})`}" |
| | | > |
| | | <img :src="getAssets(item.logo)" alt=""> |
| | | <div class="item-right"> |
| | | <div class="item-title">{{ item.name }}</div> |
| | | <div class="num-value">1</div> |
| | | </div> |
| | | |
| | | <div class="num-list"> |
| | | |
| | | </div> |
| | | </div> |
| | | <RouterView /> |
| | | </div> |
| | |
| | | |
| | | |
| | | <script setup> |
| | | |
| | | import { reactive } from 'vue'; |
| | | import { getAssets } from '@/utils' |
| | | import { reactive, toRefs, onMounted } from 'vue'; |
| | | import { RouterView } from 'vue-router' |
| | | |
| | | // const layoutList = [ |
| | | // { bgImg: requir('@/assets/img/bg_zhixingzhong@2x.png'), name: '执行中计划数(个)', logo: requir('@/assets/img') } |
| | | // ] |
| | | const layoutList = [ |
| | | { bgImg: 'bg_zhixingzhong@2x.png', name: '执行中计划数(个)', logo: 'ic_zhixingzhong@2x.png' }, |
| | | { bgImg: 'bg_yanqijihua@2x.png', name: '延期计划数(个)', logo: 'ic_yanqijihua@2x.png' }, |
| | | { bgImg: 'bg_jinrirenshu@2x.png', name: '今日生产人数(人)', logo: 'ic_jinrirenshu@2x.png' }, |
| | | { bgImg: 'bg_jinrishebei@2x.png', name: '今日生产设备(台)', logo: 'ic_jinrishebei@2x.png' }, |
| | | { bgImg: 'bg_jinribuliang@2x.png', name: '今日不良品率(%)', logo: 'ic_jinribuliang@2x.png' }, |
| | | ] |
| | | const data = reactive({ |
| | | tempCom: { name: '豆米科技' }, |
| | | isFull: false, |
| | | tempDate: { |
| | | time: '', |
| | | date: '', |
| | | day: '' |
| | | } |
| | | }) |
| | | |
| | | let { tempCom, isFull, tempDate } = toRefs(data) |
| | | |
| | | const comList = [ |
| | | {name: '豆米'}, |
| | | {name: '大米'}, |
| | | {name: '小米'}, |
| | | {name: '黄米'}, |
| | | ] |
| | | |
| | | |
| | | const selectCom = (item, index) => { |
| | | data.tempCom = item |
| | | } |
| | | |
| | | const fullChange = () => { |
| | | data.isFull = !data.isFull |
| | | let element = document.documentElement; |
| | | if (data.isFull) { // 全屏 |
| | | if (element.requestFullscreen) { |
| | | element.requestFullscreen(); |
| | | } else if (element.webkitRequestFullScreen) { |
| | | element.webkitRequestFullScreen(); |
| | | } else if (element.mozRequestFullScreen) { |
| | | element.mozRequestFullScreen(); |
| | | } else if (element.msRequestFullscreen) { |
| | | // IE11 |
| | | element.msRequestFullscreen(); |
| | | } |
| | | } else { // 还原 |
| | | if (document.exitFullscreen) { |
| | | document.exitFullscreen(); |
| | | } else if (document.webkitCancelFullScreen) { |
| | | document.webkitCancelFullScreen(); |
| | | } else if (document.mozCancelFullScreen) { |
| | | document.mozCancelFullScreen(); |
| | | } else if (document.msExitFullscreen) { |
| | | document.msExitFullscreen(); |
| | | } |
| | | } |
| | | // data.isFull = !data.isFull |
| | | } |
| | | |
| | | onMounted(() => { |
| | | |
| | | const week = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日',] |
| | | setInterval(() => { |
| | | let date = new Date() |
| | | data.tempDate = { |
| | | time: `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`, |
| | | date: `${date.getFullYear()}/${date.getMonth()+1}/${date.getDate()}`, |
| | | day: week[date.getDay()-1] |
| | | } |
| | | }, 1000) |
| | | // console.log(date.getDay()); |
| | | |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | height: 74px; |
| | | display: flex; |
| | | padding-top: 1px; |
| | | padding-left: 20px; |
| | | justify-content: space-between; |
| | | color: #fff; |
| | | .header-item { |
| | | width: 200px; |
| | | width: 300px; |
| | | } |
| | | .eare-title { |
| | | margin-top: 27px; |
| | | color: #fff; |
| | | height: 20px; |
| | | font-size: 20px; |
| | | font-family: SourceHanSansSC-Medium, SourceHanSansSC; |
| | | font-weight: 500; |
| | | // line-height: 74px; |
| | | display: flex; |
| | | .right-icon { |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-left: 8px; |
| | | } |
| | | } |
| | | .title { |
| | | margin-top: 15px; |
| | |
| | | line-height: 25px; |
| | | text-align: center; |
| | | } |
| | | .right { |
| | | margin-top: 20px; |
| | | height: 30px; |
| | | display: flex; |
| | | padding-right: 22px; |
| | | flex-direction: row-reverse; |
| | | .full-ic { |
| | | margin-top: 2px; |
| | | width: 30px; |
| | | height: 30px; |
| | | } |
| | | .right-line { |
| | | width: 2px; |
| | | height: 34px; |
| | | margin-left: 15px; |
| | | margin-right: 15px; |
| | | } |
| | | .date { |
| | | .time { |
| | | height: 20px; |
| | | font-size: 18px; |
| | | font-weight: 500; |
| | | color: #FFFFFF; |
| | | line-height: 20px; |
| | | } |
| | | .day { |
| | | height: 12px; |
| | | font-size: 12px; |
| | | font-weight: 400; |
| | | color: #D2E0FF; |
| | | line-height: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .num-list { |
| | | margin-top: 24px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | height: 88px; |
| | | color: white; |
| | | .num-item { |
| | | width: calc(25% - 50px); |
| | | background-size: 100% 100%; |
| | | margin-right: 25px; |
| | | padding-left: 30px; |
| | | padding-top: 12px; |
| | | display: flex; |
| | | &:last-child { |
| | | margin-right: 0px; |
| | | } |
| | | img { |
| | | width: 52px; |
| | | height: 52px; |
| | | } |
| | | .item-right { |
| | | margin-left: 12px; |
| | | .item-title { |
| | | height: 19px; |
| | | font-size: 13px; |
| | | font-weight: 400; |
| | | color: rgba(255,255,255,0.9); |
| | | line-height: 19px; |
| | | } |
| | | .num-value { |
| | | height: 35px; |
| | | font-size: 30px; |
| | | font-weight: bold; |
| | | color: #FFFFFF; |
| | | line-height: 35px; |
| | | background: linear-gradient(180deg, #EEEEEE 0%, #15CFFF 100%); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="content"> |
| | | <div class="content1"> |
| | | <div class="content_left"> |
| | | <div class="content_left_item1"> |
| | | <div class="content_left_item1_head"> |
| | |
| | | <span>仓库实时余量统计</span> |
| | | </div> |
| | | <div class="content_left_item2_content"> |
| | | <div class="productProcess"> |
| | | |
| | | <!-- 如果页面刷新数据比较频繁,可以将loading、showFlag的相关代码删除,防止过于频繁的出现加载动画 --> |
| | | <div class="loading_div" v-show="!showFlag"> |
| | | <div>Loading...</div> <!-- 这个loading自己写,代码没贴出来 --> |
| | | <div class="item2_content_head"> |
| | | <div class="item2_content_head_item">物料名称 / 工序</div> |
| | | <div class="item2_content_head_item">仓库</div> |
| | | <div class="item2_content_head_item">货架</div> |
| | | <div class="item2_content_head_item">数量</div> |
| | | </div> |
| | | |
| | | <div class="success_info_body" v-show="showFlag"> |
| | | <!-- 参数名称、列数根据实际情况调整 --> |
| | | <div class="table_body"> |
| | | <div class="table_th"> |
| | | <div class="tr1 th_style">排产编号</div> |
| | | <div class="tr2 th_style">类型</div> |
| | | <div class="tr3 th_style">日期</div> |
| | | <div class="tr4 th_style">进度</div> |
| | | </div> |
| | | <div class="table_main_body"> |
| | | <div class="table_inner_body" :style="{top: tableTop + 'px'}"> |
| | | <div class="table_tr" v-for="(item,index) in tableList" :key="index"> |
| | | <div class="tr1 tr">{{item.planNo}}</div> |
| | | <div class="tr2 tr">{{item.type}}</div> |
| | | <div class="tr3 tr" v-if="item.startDate!='-'">{{item.startDate}} ~ {{item.endDate}}</div> |
| | | <div class="tr3 tr" v-else>-</div> |
| | | <div class="tr4 tr" v-if="item.process!='-'">{{Number(item.process).toFixed(2)}} %</div> |
| | | <div class="tr4 tr" v-else>-</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" class="main_container"> |
| | | <div ref="scrollContainer" class="scroll_container"> |
| | | <div v-for="(item, index) in listData" :key="item.id" :class="index % 2 == 0 ? 'scroll_item scroll_item_bg1' : 'scroll_item scroll_item_bg2'"> |
| | | <span>{{ item.name }}</span> |
| | | <div class="scroll_item_row"></div> |
| | | <div class="scroll_item_row"></div> |
| | | <div class="scroll_item_row"></div> |
| | | <div class="scroll_item_row"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {reactive, ref, onMounted, onBeforeUnmount, onUnmounted, nextTick} from 'vue' |
| | | |
| | | let timer = ref(null) |
| | | let scrollContainer = ref(null) |
| | | let listData = reactive([ |
| | | {name: 'dom第一个'}, |
| | | {name: 'dom第二个'}, |
| | | {name: 'dom第三个'}, |
| | | {name: 'dom第四个'}, |
| | | {name: 'dom第五个'}, |
| | | {name: 'dom第六个'}, |
| | | {name: 'dom第七个'}, |
| | | {name: 'dom第八个'}, |
| | | {name: 'dom第九个'}, |
| | | {name: 'dom第十个'}, |
| | | ]) |
| | | start() |
| | | // 注:示例中的 listData 写的是静态数据,可以直接调用 start() |
| | | // 如果是接口获取 listData 列表时,需要在 nextTick 中调用 start() |
| | | // 否则,进入页面不会滚动。必须鼠标移入移出才会滚动 |
| | | // 用 nextTick 的原因是需要等 dom 元素加载完毕后再执行方法 |
| | | |
| | | // let chartData = reactive({ |
| | | // data: [] |
| | | // }) |
| | | // function getSensorData() { |
| | | // GetSensorData().then(res=> { |
| | | // chartData.data = res.data.data |
| | | // nextTick(()=>{ |
| | | // start() |
| | | // }) |
| | | // }) |
| | | // } |
| | | |
| | | // onMounted(()=> { |
| | | // getSensorData() |
| | | // }) |
| | | |
| | | onBeforeUnmount(()=>{ |
| | | clearTimeout(timer.value) |
| | | }) |
| | | onUnmounted(()=>{ |
| | | clearTimeout(timer.value) |
| | | }) |
| | | |
| | | function handleMouseEnter() { |
| | | clearTimeout(timer.value) |
| | | } |
| | | function handleMouseLeave() { |
| | | start() |
| | | } |
| | | // 开启定时器 |
| | | function start() { |
| | | clearTimeout(timer.value) |
| | | // 定时器触发周期 |
| | | let speed = ref(25) |
| | | timer.value = setInterval(ListScroll, speed.value) |
| | | } |
| | | function ListScroll() { |
| | | let scrollDom = scrollContainer.value |
| | | // 判读组件是否渲染完成 |
| | | if(scrollDom.offsetHeight == 0) { |
| | | scrollDom = scrollContainer.value |
| | | }else { |
| | | // 如果列表数量过少不进行滚动 |
| | | if(scrollDom.children.length < 4) { |
| | | clearTimeout(timer.value) |
| | | return |
| | | } |
| | | // 组件进行滚动 |
| | | scrollDom.scrollTop += 1 |
| | | // 判断是否滚动到底部 |
| | | if(scrollDom.scrollTop == (scrollDom.scrollHeight - scrollDom.clientHeight)) { |
| | | // 获取组件第一个节点 |
| | | let first = scrollDom.children[0] |
| | | // 删除节点 |
| | | scrollDom.removeChild(first) |
| | | // 将该节点拼接到组件最后 |
| | | scrollDom.append(first) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .content { |
| | | .content1 { |
| | | width: 100%; |
| | | height: auto; |
| | | display: flex; |
| | |
| | | .content_left_item2_content { |
| | | width: 100%; |
| | | height: 361px; |
| | | padding: 20px; |
| | | box-sizing: border-box; |
| | | background: linear-gradient(180deg, rgba(52,88,159,0) 0%, rgba(0,86,255,0.4) 100%); |
| | | .item2_content_head { |
| | | width: 100%; |
| | | height: 36px; |
| | | display: flex; |
| | | align-items: center; |
| | | background: rgba(52,88,159,0.5); |
| | | .item2_content_head_item { |
| | | flex: 1; |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 13px; |
| | | font-family: PingFangSC-Medium, PingFang SC; |
| | | font-weight: 500; |
| | | color: #01D9FE; |
| | | &:first-child { |
| | | flex: 1.5; |
| | | } |
| | | } |
| | | } |
| | | .main_container { |
| | | width: 100%; |
| | | height: calc(100% - 36px); |
| | | .scroll_container { |
| | | width: 100%; |
| | | height: 100%; |
| | | overflow: hidden; |
| | | .scroll_item_bg1 { |
| | | background: rgba(52,88,159,0.2); |
| | | } |
| | | .scroll_item_bg2 { |
| | | background: rgba(52,88,159,0.5); |
| | | } |
| | | .scroll_item { |
| | | width: 100%; |
| | | height: 36px; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .content_center { |
| | | flex: 2; |
| | | margin: 0 40px; |
| | |
| | | */ |
| | | public class ProcedurePlansPageModel { |
| | | |
| | | @ApiModelProperty(value = "工序名称", example = "1") |
| | | private String procedureName; |
| | | @ApiModelProperty(value = "工序编码", example = "1") |
| | | private Integer procedureId; |
| | | @ApiModelProperty(value = "不良品率", example = "1") |
| | | private BigDecimal unqualifiedRate; |
| | | @ApiModelProperty(value = "不良品数", example = "1") |
| | | private BigDecimal unqualifiedNum; |
| | | @ApiModelProperty(value = "良品数", example = "1") |
| | | private BigDecimal qualifiedNum; |
| | | @ApiModelProperty(value = "未完工数量", example = "1") |
| | | private BigDecimal undoneNum; |
| | | @ApiModelProperty(value = "计划生产数量", example = "1") |
| | | @ApiModelProperty(value = "计划数量", example = "1") |
| | | private BigDecimal num; |
| | | @ApiModelProperty(value = "计划个数", example = "1") |
| | | private Integer planCount; |
| | | @ApiModelProperty(value = "不良品率%", example = "1") |
| | | private BigDecimal unqualifiedRate; |
| | | @ApiModelProperty(value = "物料编码") |
| | | private String materialCode; |
| | | @ApiModelProperty(value = "工序名称") |
| | | private String procedureName; |
| | | |
| | | @ApiModelProperty(value = "状态 0已生成、1已发布、2已撤回、3已取消、4已分配、5已暂停、6已完工、7已入库、8已关闭", example = "1") |
| | | private Integer status; |
| | | |
| | | } |
| | |
| | | * 最后一列的良品数/完工数:为当前产品最后一道工序的良品数/完工数; |
| | | */ |
| | | public class ProcedureProcessModel { |
| | | @ApiModelProperty(value = "工序名称", example = "1") |
| | | private String procedureName; |
| | | @ApiModelProperty(value = "工序编码", example = "1") |
| | | private Integer procedureId; |
| | | @ApiModelProperty(value = "不良品率", example = "1") |
| | | private BigDecimal unqualifiedRate; |
| | | @ApiModelProperty(value = "不良品数", example = "1") |
| | | private BigDecimal unqualifiedNum; |
| | | @ApiModelProperty(value = "良品数", example = "1") |
| | | private BigDecimal qualifiedNum; |
| | | @ApiModelProperty(value = "未完工数量", example = "1") |
| | | private BigDecimal undoneNum; |
| | | @ApiModelProperty(value = "计划数量", example = "1") |
| | | @ApiModelProperty(value = "计划生产数量", example = "1") |
| | | private BigDecimal num; |
| | | @ApiModelProperty(value = "不良品率%", example = "1") private BigDecimal unqualifiedRate; |
| | | @ApiModelProperty(value = "物料编码") |
| | | private String materialCode; |
| | | @ApiModelProperty(value = "工序名称") |
| | | private String procedureName; |
| | | |
| | | @ApiModelProperty(value = "状态 0已生成、1已发布、2已撤回、3已取消、4已分配、5已暂停、6已完工、7已入库、8已关闭", example = "1") |
| | | private Integer status; |
| | | |
| | | @ApiModelProperty(value = "计划个数", example = "1") |
| | | private Integer planCount; |
| | | |
| | | } |
| | |
| | | import doumeemes.dao.business.model.DeviceCheck; |
| | | import doumeemes.dao.ext.vo.DeviceCheckExtListVO; |
| | | import doumeemes.dao.ext.dto.QueryDeviceCheckExtDTO; |
| | | import io.lettuce.core.dynamic.annotation.Param; |
| | | |
| | | /** |
| | | * 设备巡检信息表 EXTService定义 |
| | |
| | | PageData<DeviceCheckExtListVO> findPage(PageWrap<QueryDeviceCheckExtDTO> pageWrap); |
| | | |
| | | DeviceCheck selectOneById(Integer id); |
| | | |
| | | PageData<DeviceCheckExtListVO> getDeviceCheckPage( PageWrap<QueryDeviceCheckExtDTO> pageWrap); |
| | | } |
| | |
| | | import doumeemes.dao.ext.DeviceCheckExtMapper; |
| | | import com.github.pagehelper.PageHelper; |
| | | import com.github.pagehelper.PageInfo; |
| | | import io.lettuce.core.dynamic.annotation.Param; |
| | | import org.apache.shiro.SecurityUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | List<DeviceCheckExtListVO> result = deviceCheckExtMapper.selectList(pageWrap.getModel()); |
| | | return PageData.from(new PageInfo<>(result)); |
| | | } |
| | | @Override |
| | | public PageData<DeviceCheckExtListVO> getDeviceCheckPage (PageWrap<QueryDeviceCheckExtDTO> pageWrap) { |
| | | PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity()); |
| | | List<DeviceCheckExtListVO> result = deviceCheckExtMapper.selectList(pageWrap.getModel()); |
| | | return PageData.from(new PageInfo<>(result)); |
| | | } |
| | | |
| | | @Override |
| | | public DeviceCheck selectOneById(Integer id){ |
| | |
| | | //只能查看当前根组织的数据 |
| | | pageWrap.getModel().setRootDepartId(department.getRootId()); |
| | | pageWrap.getModel().setComDepartId(departId); |
| | | PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity()); |
| | | return deviceCheckExtService.findPage(pageWrap); |
| | | return deviceCheckExtService.getDeviceCheckPage(pageWrap); |
| | | } |
| | | @Override |
| | | public List<ProcedurePlansPageModel> getProcedurePlansPage(Integer companyId, Integer departId,Integer procedureId){ |
| | |
| | | left join device d on `deviceCheck`.DEVICE_ID = d.id |
| | | left join procedures p on p.id = d.PROCEDURE_ID |
| | | left join `system_user` s on s.id = `deviceCheck`.CREATE_USER |
| | | <where> |
| | | <where> deviceCheck.deleted=0 |
| | | <if test="deviceName != null and deviceName != ''"> |
| | | AND d.NAME like concat('%',#{deviceName},'%') |
| | | </if> |