@ -0,0 +1,2 @@ |
|||
//必须使用VITE_开头的配置信息 否则无法获取 |
|||
VITE_AMAP_KEY=6a195b0300203aeb704993f1ffaf3592 |
@ -0,0 +1,2 @@ |
|||
//必须使用VITE_开头的配置信息 否则无法获取 |
|||
VITE_AMAP_KEY=6a195b0300203aeb704993f1ffaf3592 |
@ -0,0 +1,24 @@ |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
pnpm-debug.log* |
|||
lerna-debug.log* |
|||
|
|||
node_modules |
|||
dist |
|||
dist-ssr |
|||
*.local |
|||
|
|||
# Editor directories and files |
|||
.vscode/* |
|||
!.vscode/extensions.json |
|||
.idea |
|||
.DS_Store |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw? |
@ -0,0 +1,2 @@ |
|||
auto-install-peers=true |
|||
strict-peer-dependencies=false |
@ -0,0 +1,17 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<projectDescription> |
|||
<name>plant_mange_view</name> |
|||
<comment></comment> |
|||
<projects> |
|||
</projects> |
|||
<buildSpec> |
|||
<buildCommand> |
|||
<name>org.eclipse.wst.validation.validationbuilder</name> |
|||
<arguments> |
|||
</arguments> |
|||
</buildCommand> |
|||
</buildSpec> |
|||
<natures> |
|||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature> |
|||
</natures> |
|||
</projectDescription> |
@ -0,0 +1,7 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<classpath> |
|||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/> |
|||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/> |
|||
<classpathentry kind="src" path=""/> |
|||
<classpathentry kind="output" path=""/> |
|||
</classpath> |
@ -0,0 +1 @@ |
|||
org.eclipse.wst.jsdt.launching.JRE_CONTAINER |
@ -0,0 +1 @@ |
|||
Global |
@ -0,0 +1,3 @@ |
|||
{ |
|||
"recommendations": ["johnsoncodehk.volar"] |
|||
} |
@ -0,0 +1,19 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<link rel="icon" href="/favicon.ico" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=6a195b0300203aeb704993f1ffaf3592"></script> |
|||
<script>// 高德地图code |
|||
window._AMapSecurityConfig = { |
|||
securityJsCode: '50fb940b038d86d58d4febb60b3137ab' |
|||
} |
|||
</script> |
|||
<title>国家重要产品追溯体系</title> |
|||
</head> |
|||
<body> |
|||
<div id="app"></div> |
|||
<script type="module" src="/src/animalStudy/main.js"></script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,19 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<link rel="icon" href="/favicon.ico" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=6a195b0300203aeb704993f1ffaf3592"></script> |
|||
<script>// 高德地图code |
|||
window._AMapSecurityConfig = { |
|||
securityJsCode: '50fb940b038d86d58d4febb60b3137ab' |
|||
} |
|||
</script> |
|||
<title>Vite App</title> |
|||
</head> |
|||
<body> |
|||
<div id="app"></div> |
|||
<script type="module" src="/src/main.js"></script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,42 @@ |
|||
{ |
|||
"name": "vue3-vite-demo", |
|||
"private": true, |
|||
"version": "0.0.0", |
|||
"scripts": { |
|||
"初始化": "pnpm i", |
|||
"serve": "vite --mode dev", |
|||
"build": "vite build" |
|||
}, |
|||
"dependencies": { |
|||
"@amap/amap-jsapi-loader": "^1.0.1", |
|||
"@rollup/plugin-commonjs": "^25.0.4", |
|||
"@wangeditor/editor": "^5.1.23", |
|||
"@wangeditor/editor-for-vue": "^5.1.12", |
|||
"axios": "^1.4.0", |
|||
"china-area-data": "^5.0.1", |
|||
"echarts": "^5.4.2", |
|||
"element-plus": "^2.3.7", |
|||
"highlight.js": "^11.8.0", |
|||
"jquery": "^3.7.1", |
|||
"qrcode.vue": "3.4.1", |
|||
"vant": "^4.9.6", |
|||
"vite-plugin-html": "^3.2.2", |
|||
"vite-plugin-require-transform": "^1.0.4", |
|||
"vue": "^3.3.4", |
|||
"vue-echarts": "^6.6.0", |
|||
"vue-router": "^4.2.4", |
|||
"vue3-video-play": "^1.3.1-beta.6", |
|||
"vuex": "^4.1.0", |
|||
"xlsx-js-style": "^1.2.0" |
|||
}, |
|||
"devDependencies": { |
|||
"@vitejs/plugin-vue": "^2.3.3", |
|||
"@vitejs/plugin-vue-jsx": "^1.3.10", |
|||
"black-knight": "1.3.33", |
|||
"less": "^4.1.3", |
|||
"less-loader": "~7.3.0", |
|||
"sass-resources-loader": "^2.2.5", |
|||
"vite": "^4.4.9", |
|||
"vite-plugin-vue-devtools": "^1.0.0-rc.3" |
|||
} |
|||
} |
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,59 @@ |
|||
|
|||
<template> |
|||
<router-view :key="$route.fullPath"/> |
|||
</template> |
|||
<script setup> |
|||
import { computed, inject, onMounted, provide, shallowRef, watch, ref } from 'vue' |
|||
import {useRoute, useRouter} from "vue-router" |
|||
import request,{host} from "@/config/request" |
|||
import rePassword from '@/view/accountMana/rePassword.vue' |
|||
|
|||
let {getters, commit, dispatch} =inject("store") |
|||
var router = useRouter() |
|||
provide("route", useRoute())//全局导入路由属性 |
|||
provide("router", router) |
|||
var msg=inject('msg') |
|||
|
|||
//获取用户企业基本消息 |
|||
watch(()=>!!getters['data/token']&&!!getters['data/userInfo'].companyId, async (n)=>{ |
|||
if(n){ |
|||
dispatch('data/getCompany')//企业信息 |
|||
dispatch('data/getLegalInfo')//法人信息 |
|||
} |
|||
},{immediate:true}) |
|||
//获取站点信息 |
|||
async function getDevice(){ |
|||
var res=await request("/suyuan/device/queryDeviceInfo") |
|||
if(res.statu){ |
|||
commit('data/setDevice',res.data) |
|||
if(!getters['data/token']){ |
|||
if(res.data.showTable==1){ |
|||
router.push({path:'/home'}) |
|||
}else{ |
|||
router.push({path:'/login'}) |
|||
} |
|||
} |
|||
document.querySelector('link[rel="icon"]').href=`${host('imgurl')}/${res.data.logo}` |
|||
document.title=res.data.systemName||document.title |
|||
}else{ |
|||
msg.error(res.msg,'获取站点信息失败!') |
|||
} |
|||
} |
|||
|
|||
//监听登录获取菜单 |
|||
watch(()=>getters['data/token'], n=>{ |
|||
if(n){ |
|||
dispatch('data/getMenu', true) |
|||
} |
|||
},{immediate:true}) |
|||
|
|||
onMounted(()=>{ |
|||
commit("data/setRouter",router) |
|||
getDevice() |
|||
}) |
|||
|
|||
window.onbeforeunload=e=>{ |
|||
sessionStorage.setItem('userInfo',JSON.stringify(getters['data/userInfo'])) |
|||
sessionStorage.setItem('token',getters['data/token']||'') |
|||
} |
|||
</script> |
@ -0,0 +1,99 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.content{ |
|||
position:relative; |
|||
&+*{ |
|||
margin-top:20px; |
|||
} |
|||
&:not(.last):before{ |
|||
content:""; |
|||
position:absolute; |
|||
height:100%; |
|||
border-left:1px dashed #546FD6; |
|||
left:5px; |
|||
top:17px; |
|||
} |
|||
.date{ |
|||
margin-top:10px; |
|||
padding-left:20px; |
|||
position:relative; |
|||
&:before{ |
|||
content:""; |
|||
width:15px; |
|||
height:15px; |
|||
border-radius: 50%; |
|||
top:0; |
|||
left:0; |
|||
position:absolute; |
|||
background:radial-gradient(#546FD6 4px,rgba(84, 110, 214, 0.5) 4.3px ) |
|||
} |
|||
} |
|||
.item{ |
|||
margin-left:20px; |
|||
.dec{ |
|||
width:100%; |
|||
padding:10px; |
|||
background:#F6F8FF; |
|||
color:#546FD6; |
|||
margin-top:10px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="流产记录" ref="foldDom" v-if="modelValue?.length>0"> |
|||
<div class="content" :class="{last:k>=modelValue.length-1}" v-for="(v,k) in (modelValue||[]).slice(0,2)" :key="k"> |
|||
<div class="date"> |
|||
{{new Date(v.abortDate).format('yyyy-MM-dd')}} |
|||
</div> |
|||
<div class="item"> |
|||
<span>配种日期:</span> <span>{{new Date(v.matingDate).format('yyyy-MM-dd')}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>妊娠天数:</span> <span>{{v.pregnancyDay||comAge(v)}}天</span> |
|||
</div> |
|||
<div class="item block"> |
|||
<span>流产原因:</span> <span class="dec">{{v.abortReason}}</span> |
|||
</div> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.length>=2" @click="detailDom.open()">查看更多>></div> |
|||
<van-empty v-if="!modelValue?.length>0" description="暂无数据"/> |
|||
</fold> |
|||
<detailList |
|||
ref="detailDom" |
|||
title="流产记录" |
|||
type="abort" |
|||
:head="['流产日期','配种日期','妊娠天数','流产原因']"> |
|||
<template #default="{data}"> |
|||
<td><span>{{new Date(data.abortDate).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{new Date(data.matingDate).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{data.pregnancyDay||comAge(data)}}</span></td> |
|||
<td><span style="width:auto;max-width:150px;">{{data.abortReason||0}}</span></td> |
|||
</template> |
|||
</detailList> |
|||
</template> |
|||
<script setup> |
|||
import { nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import detailList from './detailList.vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:[Array,Object], |
|||
default:null, |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var foldDom=ref() |
|||
|
|||
function comAge(val){ |
|||
return val.abortDate&&val.matingDate?Math.round((new Date(val.abortDate)-new Date(val.matingDate))/1000/60/60/24):0 |
|||
} |
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,168 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.SY-dingweixiao{ |
|||
margin-top:10px; |
|||
color:#5A74D9; |
|||
font-size:12px; |
|||
font-weight: bold; |
|||
&:before{ |
|||
font-size:16px; |
|||
text-shadow: 0px 1px 2px #5A74D9; |
|||
margin-right:4px; |
|||
font-weight: normal; |
|||
} |
|||
} |
|||
.van-swipe{ |
|||
margin-top:10px; |
|||
img{ |
|||
width:100%; |
|||
height:172px; |
|||
border-radius: 6px; |
|||
object-fit: cover; |
|||
} |
|||
} |
|||
.map:deep{ |
|||
margin-top:10px; |
|||
height:140px; |
|||
.companyName{ |
|||
font-size:12px; |
|||
position:absolute; |
|||
transform: translate(-50%, calc(-100% - 10px)); |
|||
width:max-content; |
|||
text-align: center; |
|||
max-width: 150px; |
|||
min-width: 40px; |
|||
background:#5A74D9; |
|||
color:#fff; |
|||
padding:7px; |
|||
border-radius: 8px; |
|||
&:before{ |
|||
content:""; |
|||
position:absolute; |
|||
border-top:10px solid #5A74D9; |
|||
border-right:10px solid transparent; |
|||
border-bottom:10px solid transparent; |
|||
border-left:10px solid transparent; |
|||
top:100%; |
|||
left:50%; |
|||
transform: translateX(-50%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.imgLine{ |
|||
display: flex; |
|||
align-items: center; |
|||
position:relative; |
|||
padding-left:20px; |
|||
&:before{ |
|||
content:""; |
|||
position:absolute; |
|||
width:8px; |
|||
height:8px; |
|||
transform: rotate(45deg); |
|||
background:#5A74D9; |
|||
left:0px; |
|||
} |
|||
&:not(:last-child):after{ |
|||
content:""; |
|||
height:calc(100% + 5px); |
|||
border-left:1px dashed #5A74D9; |
|||
position:absolute; |
|||
left:3px; |
|||
top:50%; |
|||
} |
|||
&+.imgLine{ |
|||
margin-top:12px; |
|||
} |
|||
.date{ |
|||
font-size:12px; |
|||
margin-right:22px; |
|||
} |
|||
.van-image{ |
|||
width:89px; |
|||
height:66px; |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold title="养殖过程信息" ref="foldDom"> |
|||
<div class="title">养殖基础信息</div> |
|||
<div class="SY-dingweixiao">{{modelValue?.name}}</div> |
|||
<van-swipe :autoplay="3000" indicator-color="white"> |
|||
<van-swipe-item v-for="(v,k) in modelValue?.pic?.split(',')?.filter(v=>v)||[]" :key="k"> |
|||
<img :src="`${host('imgurl')}/${v}`"/> |
|||
</van-swipe-item> |
|||
</van-swipe> |
|||
|
|||
<div class="item"> |
|||
<span>养殖企业:</span> <span class="left">{{modelValue?.companyName}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>养殖规模:</span> <span class="left">{{modelValue?.realArea}}亩</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>养殖区域:</span> <span class="left">{{modelValue?.address}}</span> |
|||
</div> |
|||
<div class="map" ref="mapDom"/> |
|||
<template v-if="modelValue?.partNum"> |
|||
<div class="title" style="margin-top:15px;">牛舍信息</div> |
|||
<div class="item"> |
|||
<span style="color:#999;">所属分区</span> <span style="color:#EE2746;">{{modelValue?.partNum}}</span> |
|||
</div> |
|||
</template> |
|||
<template #extra> |
|||
<slot /> |
|||
</template> |
|||
</fold> |
|||
</template> |
|||
<script setup> |
|||
import { computed, inject, nextTick, onMounted, ref, shallowRef, watch } from 'vue' |
|||
import dDialog from '../dialog.vue' |
|||
import fold from '../fold.vue' |
|||
import AMAPLoader from '@amap/amap-jsapi-loader' |
|||
import {host} from '@/config/request' |
|||
import {preview} from '@/config/utils' |
|||
import {getFarmImg} from '@/config/api' |
|||
|
|||
var dialog=inject('dialog') |
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:Object, |
|||
default:null |
|||
}, |
|||
}) |
|||
|
|||
var detectImg=computed(()=>props.modelValue?.dormitoryVo?.pic?.split?.(',')?.filter(v=>v)||[]) |
|||
var mapDom=ref() |
|||
var foldDom=ref() |
|||
|
|||
onMounted(()=>{ |
|||
AMAPLoader.reset() |
|||
AMAPLoader.load({ |
|||
key:"57fe0266af0ce01d64f1567784964340", |
|||
version:"2.0", |
|||
plugins:["AMap.Geolocation","AMap.PolygonEditor"], |
|||
}).then(AMap=>{ |
|||
var map = new AMap.Map(mapDom.value,{ |
|||
zoom:14, |
|||
zooms:[2,18], |
|||
center:[101.8698608, 25.6893628], |
|||
}) |
|||
|
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value.refresh() |
|||
}) |
|||
if(n?.lnglat){ |
|||
var marker=new AMap.Marker({ |
|||
position:n.lnglat.split(',').filter(v=>v).map(v=>parseFloat(v)), |
|||
content:`<div class="companyName">${n.name}</div>`, |
|||
}) |
|||
map.add(marker) |
|||
map.setFitView(); |
|||
} |
|||
},{immediate:true}) |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,141 @@ |
|||
<style lang="less" scoped> |
|||
// .card{ |
|||
.content{ |
|||
position:relative; |
|||
&+*{ |
|||
margin-top:20px; |
|||
} |
|||
&:not(.last):before{ |
|||
content:""; |
|||
position:absolute; |
|||
height:calc(100% + 4px); |
|||
border-left:1px dashed #546FD6; |
|||
left:7px; |
|||
top:15px; |
|||
border-bottom:1px solid #eee; |
|||
} |
|||
.date{ |
|||
margin-top:10px; |
|||
padding-left:20px; |
|||
position:relative; |
|||
&:before{ |
|||
content:""; |
|||
width:15px; |
|||
height:15px; |
|||
border-radius: 50%; |
|||
top:0; |
|||
left:0; |
|||
position:absolute; |
|||
background:radial-gradient(#546FD6 4px,rgba(84, 110, 214, 0.5) 4.3px ) |
|||
} |
|||
} |
|||
.item{ |
|||
margin-left:20px; |
|||
display: flex; |
|||
margin-top:15px; |
|||
&>span{ |
|||
font-size:12px; |
|||
&:first-child{ |
|||
color:#999; |
|||
margin-right:10px; |
|||
flex-shrink: 0; |
|||
} |
|||
&:nth-child(2){ |
|||
margin-left:auto; |
|||
&.left{ |
|||
margin-left:0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
// } |
|||
</style> |
|||
<template> |
|||
<fold sup="产犊记录" ref="foldDom" v-if="modelValue?.length>0"> |
|||
<div class="content" :class="{last:k>=modelValue.length-1}" v-for="(v,k) in (modelValue||[]).slice(0,2)" :key="k"> |
|||
<div class="date"> |
|||
{{new Date(v.calvingDate).format('yyyy-MM-dd')}} |
|||
</div> |
|||
<div class="item"> |
|||
<span>配种日期:</span> <span>{{v.matingDate||'/'}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>妊娠天数:</span> <span>{{v.pregnancyDay||comAge(v)}}天</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>犊牛健康状态:</span> <span :style="{color: v.healthStatus=='健康'?'#64C3A4':'rgb(243, 99, 124)'}">{{v.healthStatus}}</span> |
|||
</div> |
|||
<template v-if="v.healthStatus=='健康'"> |
|||
<div class="item"> |
|||
<span>犊牛品种:</span> <span>{{v.varietyName}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>犊牛耳号:</span> <span>{{v.code}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>犊牛性别:</span> <span>{{v.sex}}</span> |
|||
</div> |
|||
</template> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.length>=2" @click="detailDom.open()">查看更多>></div> |
|||
<van-empty v-if="!modelValue?.length>0" description="暂无数据"/> |
|||
</fold> |
|||
<detailList |
|||
ref="detailDom" |
|||
title="产犊记录" |
|||
type="caving" |
|||
:head="['日期','妊娠天数','产犊那难易度','产犊详情']"> |
|||
<template #content="{data}"> |
|||
<div class="content" :class="{last:k>=data.length-1}" v-for="(v,k) in (data||[])" :key="k"> |
|||
<div class="date"> |
|||
{{new Date(v.calvingDate).format('yyyy-MM-dd')}} |
|||
</div> |
|||
<div class="item"> |
|||
<span>配种日期:</span> <span>{{v.matingDate||'/'}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>妊娠天数:</span> <span>{{v.pregnancyDay||comAge(v)}}天</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>犊牛健康状态:</span> <span :style="{color: v.healthStatus=='健康'?'#64C3A4':'rgb(243, 99, 124)'}">{{v.healthStatus}}</span> |
|||
</div> |
|||
<template v-if="v.healthStatus=='健康'"> |
|||
<div class="item"> |
|||
<span>犊牛品种:</span> <span>{{v.varietyName}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>犊牛耳号:</span> <span>{{v.code}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>犊牛性别:</span> <span>{{v.sex}}</span> |
|||
</div> |
|||
</template> |
|||
</div> |
|||
</template> |
|||
</detailList> |
|||
</template> |
|||
<script setup> |
|||
import { nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import detailList from './detailList.vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:[Array,Object], |
|||
default:null, |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var foldDom=ref() |
|||
|
|||
function comAge(val){ |
|||
return val.calvingDate&&val.matingDate?Math.round((new Date(val.calvingDate)-new Date(val.matingDate))/1000/60/60/24):0 |
|||
} |
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,91 @@ |
|||
<style lang="less" scoped> |
|||
.content{ |
|||
position:relative; |
|||
padding-left:15px; |
|||
&:before{ |
|||
content:""; |
|||
width:8px; |
|||
height:8px; |
|||
background:#5a74d9; |
|||
position:absolute; |
|||
top:3px; |
|||
left:0; |
|||
transform: rotate(45deg); |
|||
} |
|||
&:not(:last-child){ |
|||
padding-bottom:10px; |
|||
&:after{ |
|||
content:""; |
|||
position:absolute; |
|||
left:4px; |
|||
top:5px; |
|||
height:100%; |
|||
border-left:1px dashed #5a74d9; |
|||
} |
|||
} |
|||
.date{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
span{ |
|||
color:#EE2746; |
|||
font-size:12px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="养殖检验信息" ref="foldEl" v-if="modelValue?.length>0"> |
|||
<div class="content" v-for="(v,k) in data" :key="k"> |
|||
<div class="date"> |
|||
{{new Date(v.detectDate).format('yyyy-MM-dd')}} <span>{{v.detectName}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>检验机构:</span> <span>{{v.detectPlace}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>检测编号:</span> <span>{{v.detectCode}}</span> |
|||
</div> |
|||
<div class="item block"> |
|||
<span>检测报告:</span> |
|||
<div class="imgs"> |
|||
<van-image |
|||
v-for="(v1,k1) in v.pic.slice(0,3)" :key="k1" |
|||
radius="4" |
|||
fit="cover" |
|||
@click="preview(k1, v.pic)" |
|||
:style="{'--n':k1==2&&v.pic.length>3?`'${v.pic.length-2}'`:''}" |
|||
:src="`${host('imgurl')}/${v1}`"> |
|||
<template v-slot:loading> |
|||
<van-loading type="spinner" size="20" /> |
|||
</template> |
|||
</van-image> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<van-empty v-if="data.length==0" description="暂无数据"/> |
|||
</fold> |
|||
</template> |
|||
<script setup> |
|||
import { computed, nextTick, ref, shallowRef, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import {host} from '@/config/request' |
|||
import {preview} from '@/config/utils' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:Array, |
|||
default:()=>[] |
|||
} |
|||
}) |
|||
|
|||
var foldEl=ref() |
|||
|
|||
var data=computed(()=>props.modelValue.map(v=>({...v,pic:v.detectReport?.split(',')?.filter?.(v=>v)||[]}))) |
|||
|
|||
watch(data, ()=>{ |
|||
nextTick(()=>{ |
|||
foldEl.value?.refresh?.() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,180 @@ |
|||
<style lang="less"> |
|||
.sanqiDialog.grow{ |
|||
--bg:#fff; |
|||
&>.title{ |
|||
padding-right:40px; |
|||
} |
|||
&>.content{ |
|||
background:#ebf0ff; |
|||
margin:10px; |
|||
border-radius: 8px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
.title{ |
|||
color:#fff; |
|||
height:30px; |
|||
border-radius: 20px 20px 0 0; |
|||
width:max-content; |
|||
margin:0 auto; |
|||
background: #546FD6; |
|||
line-height: 30px; |
|||
padding:0 20px; |
|||
position: relative; |
|||
&:before,&:after{ |
|||
content:""; |
|||
position:absolute; |
|||
border-left:10px solid #546FD6; |
|||
border-top:10px solid transparent; |
|||
border-right:10px solid transparent; |
|||
border-bottom:10px solid transparent; |
|||
bottom:-9px; |
|||
} |
|||
&:before{ |
|||
transform: rotate(-45deg); |
|||
left:4.2px; |
|||
} |
|||
&:after{ |
|||
transform: rotate(-135deg); |
|||
right:3.7px; |
|||
} |
|||
} |
|||
.list{ |
|||
flex-grow: 1; |
|||
overflow: auto; |
|||
margin-top:20px; |
|||
position:relative; |
|||
table{ |
|||
min-width:100%; |
|||
tr{ |
|||
&:first-child{ |
|||
td{ |
|||
color:#546FD6; |
|||
position:sticky; |
|||
top:0; |
|||
z-index: 10; |
|||
&:first-child{ |
|||
z-index: 50; |
|||
} |
|||
} |
|||
} |
|||
&:nth-child(2n+1)>td{ |
|||
background:#dbe4fd; |
|||
} |
|||
&:nth-child(2n)>td{ |
|||
background:#ebf0ff; |
|||
} |
|||
td{ |
|||
text-align: center; |
|||
padding:8px 7px; |
|||
vertical-align: top; |
|||
span{ |
|||
display: inline-block; |
|||
width:max-content; |
|||
} |
|||
&:first-child{ |
|||
position:sticky; |
|||
left:0; |
|||
z-index: 10; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<d-dialog class="grow" ref="dialogDom" :title="title"> |
|||
<div class="title">详细列表</div> |
|||
<div class="list" @scroll="scroll"> |
|||
<slot name="content" :data="list"> |
|||
<table> |
|||
<tr> |
|||
<td v-for="(v,k) in head" :key="k" :style="{zIndex:k?10:50}"><span>{{v}}</span></td> |
|||
</tr> |
|||
<tr v-for="(v,k) in list" :key="k"> |
|||
<slot :data='v'/> |
|||
</tr> |
|||
</table> |
|||
</slot> |
|||
</div> |
|||
</d-dialog> |
|||
</template> |
|||
<script setup> |
|||
import { inject, nextTick, reactive, ref, shallowRef } from "vue"; |
|||
import dDialog from '../dialog.vue' |
|||
import request from '@/config/request' |
|||
|
|||
var props=defineProps({ |
|||
head:{ |
|||
type:Array, |
|||
default:[] |
|||
}, |
|||
title:{ |
|||
type:String, |
|||
default:"", |
|||
}, |
|||
widths:{ |
|||
type:Object, |
|||
default:()=>({}) |
|||
}, |
|||
type:{ |
|||
type:String, |
|||
default:"", |
|||
} |
|||
}) |
|||
var dialog=inject('dialog') |
|||
var toast=inject('Toast') |
|||
var loading=false |
|||
|
|||
var searchVal=reactive({ |
|||
pageNo:1, |
|||
pageSize:15, |
|||
type:"process", |
|||
produceCode:window.location.search.match(/code=(\w+)/)?.[1], |
|||
companyId: window.location.search.match(/id=(\w+)/)?.[1], |
|||
}) |
|||
var list=shallowRef([]) |
|||
var total=ref(0) |
|||
|
|||
var dialogDom=ref() |
|||
async function search(){ |
|||
if(!loading && (total.value==0||list.value.length<total.value)){ |
|||
var res=await request("/scancode/breed/queryMoreInfoByCode",{ |
|||
method:"post", |
|||
data:{ |
|||
...searchVal, |
|||
type:props.type, |
|||
}, |
|||
}) |
|||
if(res.statu){ |
|||
list.value=list.value.concat(res.data.data) |
|||
|
|||
searchVal.pageNo++ |
|||
total.value=res.data.total |
|||
if(list.value.length==total.value)toast('加载完成!'); |
|||
}else{ |
|||
dialog({ |
|||
title:"提示", |
|||
message:res.msg||`获取${props.title}失败!` |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
function scroll(e){ |
|||
if(e.target.scrollHeight-e.target.scrollTop<=e.target.clientHeight+2){ |
|||
search() |
|||
} |
|||
} |
|||
|
|||
defineExpose({ |
|||
open(){ |
|||
dialogDom.value.open() |
|||
// searchVal.pageNo=1 |
|||
// total.value=0 |
|||
// list.value=[] |
|||
search() |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,94 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.content{ |
|||
position:relative; |
|||
&+*{ |
|||
margin-top:20px; |
|||
} |
|||
&:not(.last):before{ |
|||
content:""; |
|||
position:absolute; |
|||
height:100%; |
|||
border-left:1px dashed #546FD6; |
|||
left:5px; |
|||
top:17px; |
|||
} |
|||
.title{ |
|||
margin-top:10px; |
|||
&:before{ |
|||
border-radius: 50%!important; |
|||
width:10px!important; |
|||
height:10px!important; |
|||
background-color:transparent!important; |
|||
background-image:radial-gradient(#546FD6 3px,rgba(84, 110, 214, 0.3) 3.3px)!important; |
|||
} |
|||
.name{ |
|||
color:#EE2746; |
|||
font-size:12px; |
|||
margin-left: auto; |
|||
} |
|||
} |
|||
.item{ |
|||
margin-left:20px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="发情配种登记" ref="foldDom" v-if="modelValue?.length>0"> |
|||
<div class="content" :class="{last:k>=modelValue.length-1}" v-for="(v,k) in (modelValue||[]).slice(0,2)" :key="k"> |
|||
<div class="title"> |
|||
{{new Date(v.estrusDate).format('yyyy-MM-dd')}} |
|||
</div> |
|||
<div class="item"> |
|||
<span>发情表现</span> <span>{{v.estrusPerformance}}-{{v.estrusType}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>是否配种</span> <span>{{v.flagMating}}</span> |
|||
</div> |
|||
<template v-if="v.flagMating=='配种'"> |
|||
<div class="item"> |
|||
<span>配种方式</span> <span>{{v.matingWay}}</span> |
|||
</div> |
|||
<!-- <div class="item"> |
|||
<span>配种员</span> <span>{{v.matingPeo}}</span> |
|||
</div> --> |
|||
</template> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.length>=2" @click="detailDom.open()">查看更多>></div> |
|||
<van-empty v-if="!modelValue?.length>0" description="暂无数据"/> |
|||
</fold> |
|||
<detailList |
|||
ref="detailDom" |
|||
title="发情配种登记" |
|||
type="mating" |
|||
:head="['日期','发情表现','发情类别','是否配种','配种方式']"> |
|||
<template #default="{data}"> |
|||
<td><span>{{new Date(data.estrusDate).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{data.estrusPerformance}}</span></td> |
|||
<td><span>{{data.estrusType}}</span></td> |
|||
<td><span>{{data.flagMating}}</span></td> |
|||
<td><span v-if="data.flagMating=='配种'">{{data.matingWay}}</span></td> |
|||
</template> |
|||
</detailList> |
|||
</template> |
|||
<script setup> |
|||
import { computed, nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import detailList from './detailList.vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:[Array,Object], |
|||
default:null, |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var foldDom=ref() |
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,99 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.van-swipe{ |
|||
margin-top:10px; |
|||
img{ |
|||
width:100%; |
|||
height:172px; |
|||
border-radius: 6px; |
|||
object-fit: cover; |
|||
} |
|||
} |
|||
&>.seniority{ |
|||
margin-bottom:10px; |
|||
.btn{ |
|||
margin-left:auto; |
|||
display: flex; |
|||
span{ |
|||
font-size:9px; |
|||
color:#999; |
|||
background:#E7EDFD; |
|||
height:20px; |
|||
line-height: 20px; |
|||
width:30px; |
|||
text-align: center; |
|||
&.active{ |
|||
color:#fff; |
|||
background:#546FD6; |
|||
} |
|||
&:first-child{ |
|||
border-radius: 20px 0 0 20px; |
|||
} |
|||
&:nth-child(2){ |
|||
border-radius:0 20px 20px 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold title="牛只档案信息" ref="foldDom"> |
|||
<div style="color:#EE2746;font-weight:bold;font-size:22px;">{{modelValue?.varietyName}}</div> |
|||
<div class="item"> |
|||
<span>编号:</span> <span>{{modelValue?.produceCode}}</span> |
|||
</div> |
|||
<!-- <div class="item"> |
|||
<span>肉牛登记号:</span> <span>{{modelValue?.beefCattleCode}}</span> |
|||
</div> --> |
|||
<div class="line"> |
|||
<div class="item"> |
|||
<span>畜 别:</span> <span>{{modelValue?.sex}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>毛 色:</span> <span>{{modelValue?.furColor}}</span> |
|||
</div> |
|||
</div> |
|||
<div class="line"> |
|||
<div class="item"> |
|||
<span>出生日期:</span> <span>{{modelValue?.birthDate||'/'}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>出生重量:</span> <span>{{modelValue?.weight||'/'}}</span> |
|||
</div> |
|||
</div> |
|||
<div class="title" style="margin:15px 0;">图片</div> |
|||
<van-swipe :autoplay="3000" indicator-color="white"> |
|||
<van-swipe-item v-for="(v,k) in modelValue?.pic?.split?.(',')?.filter?.(v=>v)||[]" :key="k"> |
|||
<img :src="`${host('imgurl')}/${v}`"/> |
|||
</van-swipe-item> |
|||
</van-swipe> |
|||
<van-empty v-if="!modelValue?.pic" description="暂无图片"/> |
|||
<template #extra> |
|||
<slot/> |
|||
</template> |
|||
</fold> |
|||
</template> |
|||
<script setup> |
|||
import fold from '../fold.vue' |
|||
import {host} from '@/config/request' |
|||
import { computed, nextTick, ref, watch } from 'vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:Object, |
|||
default:null |
|||
} |
|||
}) |
|||
|
|||
var foldDom=ref() |
|||
var relation=ref('父辈') |
|||
var seniority=computed(()=>props.farther?.find(v=>v.relation==relation.value)) |
|||
watch(()=>props.modelValue, n=>{ |
|||
if(n){ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,196 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.content{ |
|||
position:relative; |
|||
&+*{ |
|||
margin-top:20px; |
|||
} |
|||
&:not(.last):before{ |
|||
content:""; |
|||
position:absolute; |
|||
height:100%; |
|||
border-left:1px dashed #546FD6; |
|||
left:5px; |
|||
top:17px; |
|||
} |
|||
.title{ |
|||
margin-top:10px; |
|||
&:before{ |
|||
border-radius: 1px!important; |
|||
width:10px!important; |
|||
height:10px!important; |
|||
transform: rotate(45deg); |
|||
margin-left:1px; |
|||
} |
|||
.name{ |
|||
color:#EE2746; |
|||
font-size:12px; |
|||
margin-left: auto; |
|||
} |
|||
} |
|||
.items{ |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
margin:10px -9px 0 20px; |
|||
span{ |
|||
width:calc(100%/3 - 9px); |
|||
margin:0 9px 15px 0; |
|||
height:50px; |
|||
background:#F7F9FF; |
|||
border-radius: 5px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size:13px; |
|||
position:relative; |
|||
padding-top:10px; |
|||
&:before{ |
|||
content:attr(data-name); |
|||
position:absolute; |
|||
top:0; |
|||
left:0; |
|||
border-radius: 5px 0; |
|||
background:#D2DDFF; |
|||
color:#546FD6; |
|||
font-size:10px; |
|||
height:17px; |
|||
line-height: 17px; |
|||
padding:0 5px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.grow{ |
|||
.title{ |
|||
color:#fff; |
|||
height:30px; |
|||
border-radius: 20px 20px 0 0; |
|||
width:max-content; |
|||
margin:0 auto; |
|||
background: #546FD6; |
|||
line-height: 30px; |
|||
padding:0 20px; |
|||
position: relative; |
|||
&:before,&:after{ |
|||
content:""; |
|||
position:absolute; |
|||
border-left:10px solid #546FD6; |
|||
border-top:10px solid transparent; |
|||
border-right:10px solid transparent; |
|||
border-bottom:10px solid transparent; |
|||
bottom:-9px; |
|||
} |
|||
&:before{ |
|||
transform: rotate(-45deg); |
|||
left:4.2px; |
|||
} |
|||
&:after{ |
|||
transform: rotate(-135deg); |
|||
right:3.7px; |
|||
} |
|||
} |
|||
.list{ |
|||
flex-grow: 1; |
|||
overflow: auto; |
|||
margin-top:20px; |
|||
position:relative; |
|||
table{ |
|||
min-width:100%; |
|||
tr{ |
|||
&:first-child{ |
|||
td{ |
|||
color:#546FD6; |
|||
position:sticky; |
|||
top:0; |
|||
z-index: 10; |
|||
} |
|||
} |
|||
&:nth-child(2n+1)>td{ |
|||
background:#dbe4fd; |
|||
} |
|||
&:nth-child(2n)>td{ |
|||
background:#ebf0ff; |
|||
} |
|||
td{ |
|||
text-align: center; |
|||
padding:8px 7px; |
|||
span{ |
|||
display: inline-block; |
|||
width:max-content; |
|||
} |
|||
&:first-child{ |
|||
position:sticky; |
|||
left:0; |
|||
z-index: 10; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold title="生长检测信息" ref="foldDom"> |
|||
<div class="title">生长发育信息</div> |
|||
<div class="content" :class="{last:k>=modelValue.length-1}" v-for="(v,k) in modelValue" :key="k"> |
|||
<div class="title"> |
|||
{{new Date(v.detectionTime).format('yyyy-MM-dd')}} |
|||
<span class="name">{{v.detectionPeo}}</span> |
|||
</div> |
|||
<div class="items"> |
|||
<span data-name="体重">{{v.weight||0}}kg</span> |
|||
<span data-name="体高">{{v.height||0}}cm</span> |
|||
<span data-name="十字部高">{{v.crossHeight||0}}cm</span> |
|||
<span data-name="体斜长">{{v.plagioclase||0}}cm</span> |
|||
<span data-name="胸围">{{v.bust||0}}cm</span> |
|||
<span data-name="腹围">{{v.abdominalLength}}cm</span> |
|||
<span data-name="管围">{{v.cannonCircum}}cm</span> |
|||
<span data-name="睾丸围">{{v.testisCircum||0}}cm</span> |
|||
</div> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.length>=2" @click="detailDom.open()">查看更多>></div> |
|||
<van-empty v-if="!modelValue?.length>0" description="暂无数据"/> |
|||
<template #extra> |
|||
<slot /> |
|||
</template> |
|||
</fold> |
|||
|
|||
<detailList |
|||
ref="detailDom" |
|||
title="生长发育信息" |
|||
type="grow" |
|||
:head="['日期','体重(kg)','体高(cm)','十字部高(cm)','体斜长(cm)','胸围(cm)','腹围(cm)','管围(cm)','睾丸围(cm)']"> |
|||
<template #default="{data}"> |
|||
<td><span>{{new Date(data.detectionTime).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{data.weight||0}}</span></td> |
|||
<td><span>{{data.height||0}}</span></td> |
|||
<td><span>{{data.crossHeight||0}}</span></td> |
|||
<td><span>{{data.plagioclase||0}}</span></td> |
|||
<td><span>{{data.bust||0}}</span></td> |
|||
<td><span>{{data.abdominalLength||0}}</span></td> |
|||
<td><span>{{data.cannonCircum||0}}</span></td> |
|||
<td><span>{{data.testisCircum||0}}</span></td> |
|||
</template> |
|||
</detailList> |
|||
</template> |
|||
<script setup> |
|||
import { nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import detailList from './detailList.vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:[Array,Object], |
|||
default:null |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var foldDom=ref() |
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,90 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.content{ |
|||
position:relative; |
|||
&+*{ |
|||
margin-top:20px; |
|||
} |
|||
&:not(.last):before{ |
|||
content:""; |
|||
position:absolute; |
|||
height:100%; |
|||
border-left:1px dashed #546FD6; |
|||
left:5px; |
|||
top:17px; |
|||
} |
|||
.title{ |
|||
margin-top:10px; |
|||
&:before{ |
|||
border-radius: 1px!important; |
|||
width:10px!important; |
|||
height:10px!important; |
|||
transform: rotate(45deg); |
|||
margin-left:1px; |
|||
} |
|||
.name{ |
|||
color:#EE2746; |
|||
font-size:12px; |
|||
margin-left: auto; |
|||
} |
|||
} |
|||
.item{ |
|||
margin-left:20px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="超声波活体检测" ref="foldDom" v-if="modelValue?.length>0"> |
|||
<div class="content" :class="{last:k>=modelValue.length-1}" v-for="(v,k) in modelValue||[]" :key="k"> |
|||
<div class="title"> |
|||
{{new Date(v.detectionTime).format('yyyy-MM-dd')}} |
|||
<span class="name">{{v.detectionPeo}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>背膘厚:</span> <span>{{v.backfatThickness}}mm</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>眼肌面积:</span> <span>{{v.eyeMuscleArea}}㎡</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>肌内脂肪含量:</span> <span>{{v.fatContent}}</span> |
|||
</div> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.length>=2" @click="detailDom.open()">查看更多>></div> |
|||
<van-empty v-if="!modelValue?.length>0" description="暂无数据"/> |
|||
</fold> |
|||
|
|||
<detailList |
|||
ref="detailDom" |
|||
title="超声波活体检测" |
|||
type="ultrasonic" |
|||
:head="['日期','背膘厚','眼肌面积','肌内脂肪含量']"> |
|||
<template #default="{data}"> |
|||
<td><span>{{new Date(data.detectionTime).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{data.backfatThickness||0}}</span></td> |
|||
<td><span>{{data.eyeMuscleArea||0}}</span></td> |
|||
<td><span>{{data.fatContent||0}}</span></td> |
|||
</template> |
|||
</detailList> |
|||
</template> |
|||
<script setup> |
|||
import { nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import detailList from './detailList.vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:[Array,Object], |
|||
default:null, |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var foldDom=ref() |
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,160 @@ |
|||
<style lang="less" scoped> |
|||
.van-popup{ |
|||
.info{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
span{ |
|||
font-size:12px; |
|||
color:#333; |
|||
&:before{ |
|||
content:attr(data-title)": "; |
|||
color:#707070; |
|||
} |
|||
} |
|||
} |
|||
.imgs{ |
|||
display: flex; |
|||
align-items: center; |
|||
margin:10px -15px 0 0; |
|||
.van-image{ |
|||
height:var(--h,83px); |
|||
width:calc(100%/3 - 15px); |
|||
margin-right:15px; |
|||
border-radius: 5px; |
|||
position:relative; |
|||
&:before{ |
|||
content:var(--n); |
|||
position:absolute; |
|||
top:0; |
|||
left:0; |
|||
width:100%; |
|||
height:100%; |
|||
color:#fff; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background:rgba(0, 0, 0, 0.4); |
|||
} |
|||
} |
|||
} |
|||
.line{ |
|||
border-top:1px dashed #ddd; |
|||
margin:7.5px 0; |
|||
} |
|||
.remark{ |
|||
background:#F6F8FF; |
|||
color:#546FD6; |
|||
border-radius: 6px; |
|||
padding:10px; |
|||
font-size:12px; |
|||
} |
|||
.title{ |
|||
color:#fff; |
|||
height:30px; |
|||
border-radius: 20px 20px 0 0; |
|||
width:max-content; |
|||
margin:auto; |
|||
background: #546FD6; |
|||
line-height: 30px; |
|||
padding:0 20px; |
|||
position: relative; |
|||
&:before,&:after{ |
|||
content:""; |
|||
position:absolute; |
|||
border-left:10px solid #546FD6; |
|||
border-top:10px solid transparent; |
|||
border-right:10px solid transparent; |
|||
border-bottom:10px solid transparent; |
|||
bottom:-9px; |
|||
} |
|||
&:before{ |
|||
transform: rotate(-45deg); |
|||
left:4.2px; |
|||
} |
|||
&:after{ |
|||
transform: rotate(-135deg); |
|||
right:3.7px; |
|||
} |
|||
} |
|||
table{ |
|||
width:100%; |
|||
margin-top:20px; |
|||
tr{ |
|||
font-size:12px; |
|||
&:nth-child(2n-1){ |
|||
background:#dbe4fd; |
|||
} |
|||
&:first-child{ |
|||
font-size:13px; |
|||
color:#546FD6; |
|||
} |
|||
td{ |
|||
padding:8px 5px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<d-dialog ref="dialogDom" title="养殖管理"> |
|||
<div class="info"> |
|||
<span data-title="负责人">{{detail.userName}}</span> |
|||
<span data-title="投入人力">{{detail.userNum||0}}个</span> |
|||
<span data-title="工时">{{detail.workTime||0}}天</span> |
|||
</div> |
|||
<template v-if="detail.pic.length > 0"> |
|||
<div style="font-size:12px;color:#707070;margin:10px 0;">农事图片:</div> |
|||
<div class="imgs"> |
|||
<van-image |
|||
v-for="(v,k) in detail.pic.slice(0,3)" :key="k" |
|||
radius="4" |
|||
fit="cover" |
|||
@click="preview(k,detail.pic)" |
|||
:style="{'--n':k==2&&detail.pic.length>3?`'${detail.pic.length-2}'`:''}" |
|||
:src="`${host('imgurl')}/${v}`"> |
|||
<template v-slot:loading> |
|||
<van-loading type="spinner" size="20" /> |
|||
</template> |
|||
</van-image> |
|||
</div> |
|||
</template> |
|||
<template v-if="detail.remark"> |
|||
<div style="font-size:12px;color:#707070;margin:10px 0;">备注:</div> |
|||
<div class="remark">{{detail.remark}}</div> |
|||
</template> |
|||
<template v-if="detail?.inputVos?.length>0"> |
|||
<div class="line"/> |
|||
<div class="title">投入品信息</div> |
|||
<table> |
|||
<tr> |
|||
<td><span style="display:inline-block;min-width:50px;">投入品</span></td> |
|||
<td><span style="display:inline-block;min-width:52px;">投入数量</span></td> |
|||
<td><span style="display:inline-block;width:63px;">采购日期</span></td> |
|||
<td><span>供应商</span></td> |
|||
</tr> |
|||
<tr v-for="(v,k) in detail?.inputVos" :key="k"> |
|||
<td>{{v.goodsName}}</td><td>{{v.reducedQuantity}}{{v.unit}}</td><td>{{new Date(v.inventoryDate).format('yyyy-MM-dd')}}</td><td>{{v.supplier}}</td> |
|||
</tr> |
|||
</table> |
|||
</template> |
|||
</d-dialog> |
|||
</template> |
|||
<script setup> |
|||
import { ref, shallowRef } from 'vue' |
|||
import dDialog from '../../dialog.vue' |
|||
import {host} from '@/config/request' |
|||
import {preview} from '@/config/utils' |
|||
|
|||
var dialogDom=ref() |
|||
var detail=shallowRef({}) |
|||
defineExpose({ |
|||
open(val={}){ |
|||
detail.value={ |
|||
...val, |
|||
images: val?.images?.split(',').filter(v=>v)||[] |
|||
} |
|||
dialogDom.value.open() |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,93 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.sup{ |
|||
margin-top:10px; |
|||
span{ |
|||
color:#EE2746; |
|||
font-size:23px; |
|||
font-weight: bold; |
|||
margin-left:10px; |
|||
} |
|||
} |
|||
.dateLine{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin-top:20px; |
|||
padding-left:20px; |
|||
position:relative; |
|||
&:before{ |
|||
content:""; |
|||
width:12px; |
|||
height:12px; |
|||
position:absolute; |
|||
border-radius: 50%; |
|||
background:radial-gradient(#546FD6 4px,rgba(84, 110, 214, 0.3) 4.5px); |
|||
left:0; |
|||
} |
|||
&+.dateLine:after{ |
|||
content:""; |
|||
height:calc(100% + 8px); |
|||
position:absolute; |
|||
border-left:1px dashed #546FD6; |
|||
left:6px; |
|||
bottom:12px; |
|||
} |
|||
span{ |
|||
font-size:12px; |
|||
&.date{ |
|||
color:#999; |
|||
} |
|||
&.type{ |
|||
color:#999; |
|||
} |
|||
&.btn{ |
|||
color:#546FD6; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="养殖管理信息" ref="foldDom" v-if="modelValue?.record>0"> |
|||
<div class="sup">累计操作 <span>{{modelValue?.record||0}}次</span></div> |
|||
<div class="dateLine" v-for="(v,k) in modelValue?.processVos||[]" :key="k"> |
|||
<span class="date">{{new Date(v.operationTime).format('yyyy-MM-dd')}}</span> |
|||
<span class="type">{{v.type}}</span> |
|||
<span class="btn" @click="detailDom.open({...v.detailvo,pic:v.detailvo?.pic?.split(',').filter(v=>v)})">查看详情</span> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.record>0" @click="listDom.open()">查看更多>></div> |
|||
<van-empty v-else description="暂无数据"/> |
|||
</fold> |
|||
<detail ref="detailDom"/> |
|||
<list ref="listDom" :list="modelValue" :cubId="cubId"/> |
|||
</template> |
|||
<script setup> |
|||
import { computed, inject, nextTick, onMounted, ref, shallowRef, watch } from 'vue' |
|||
import fold from '../../fold.vue' |
|||
import detail from './detail.vue' |
|||
import list from './list.vue' |
|||
import {getMana} from '@/config/api' |
|||
|
|||
var dialog=inject('dialog') |
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:Array, |
|||
default:()=>[], |
|||
}, |
|||
cubId:{ |
|||
type:String, |
|||
default:"", |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var listDom=ref() |
|||
var foldDom=ref() |
|||
|
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
},{immediate:true}) |
|||
</script> |
@ -0,0 +1,238 @@ |
|||
<style lang="less" scoped> |
|||
.van-popup{ |
|||
.block{ |
|||
background:#ebf0ff; |
|||
padding:15px; |
|||
border-radius: 8px; |
|||
&+.block{ |
|||
margin-top:15px; |
|||
} |
|||
&>.head{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin-bottom:10px; |
|||
span{ |
|||
font-size:14px; |
|||
&:first-child{ |
|||
margin-right:10px; |
|||
} |
|||
&:nth-child(2){ |
|||
color:#EE2746; |
|||
} |
|||
} |
|||
} |
|||
&>.info{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
span{ |
|||
font-size:12px; |
|||
color:#333; |
|||
&:before{ |
|||
content:attr(data-title)": "; |
|||
color:#707070; |
|||
} |
|||
} |
|||
} |
|||
&>.imgs{ |
|||
display: flex; |
|||
align-items: center; |
|||
margin:10px -15px 0 0; |
|||
.van-image{ |
|||
height:var(--h,83px); |
|||
width:calc(100%/3 - 15px); |
|||
margin-right:15px; |
|||
border-radius: 5px; |
|||
position:relative; |
|||
&:before{ |
|||
content:var(--n); |
|||
position:absolute; |
|||
top:0; |
|||
left:0; |
|||
width:100%; |
|||
height:100%; |
|||
color:#fff; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background:rgba(0, 0, 0, 0.4); |
|||
} |
|||
} |
|||
} |
|||
&>.line{ |
|||
border-top:1px dashed #ddd; |
|||
margin:7.5px 0; |
|||
} |
|||
.remark{ |
|||
background:#F6F8FF; |
|||
color:#546FD6; |
|||
border-radius: 6px; |
|||
padding:10px; |
|||
font-size:12px; |
|||
} |
|||
&>.title{ |
|||
color:#fff; |
|||
height:30px; |
|||
border-radius: 20px 20px 0 0; |
|||
width:max-content; |
|||
margin:10px auto; |
|||
background: #546FD6; |
|||
line-height: 30px; |
|||
padding:0 20px; |
|||
position: relative; |
|||
&:before,&:after{ |
|||
content:""; |
|||
position:absolute; |
|||
border-left:10px solid #546FD6; |
|||
border-top:10px solid transparent; |
|||
border-right:10px solid transparent; |
|||
border-bottom:10px solid transparent; |
|||
bottom:-9px; |
|||
} |
|||
&:before{ |
|||
transform: rotate(-45deg); |
|||
left:4.2px; |
|||
} |
|||
&:after{ |
|||
transform: rotate(-135deg); |
|||
right:3.7px; |
|||
} |
|||
} |
|||
&>table{ |
|||
width:100%; |
|||
margin-top: 20px; |
|||
tr{ |
|||
font-size:12px; |
|||
&:nth-child(2n-1){ |
|||
background:#dbe4fd; |
|||
} |
|||
&:first-child{ |
|||
font-size:13px; |
|||
color:#546FD6; |
|||
} |
|||
td{ |
|||
padding:8px 5px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<d-dialog ref="dialogDom" title="养殖管理" style="--bg:#fff;--p:15px;" @scroll="search"> |
|||
<div class="block" v-for="(v,k) in list" :key="k"> |
|||
<div class="head"> |
|||
<span>{{new Date(v.operationTime).format('yyyy-MM-dd')}}</span> |
|||
<span>{{v.type}}</span> |
|||
</div> |
|||
<div class="info"> |
|||
<span data-title="负责人">{{v.userName}}</span> |
|||
<span data-title="投入人力">{{v.userNum||0}}个</span> |
|||
<span data-title="工时">{{v.workTime||0}}天</span> |
|||
</div> |
|||
<template v-if="v.pic.length > 0"> |
|||
<div style="font-size:12px;color:#707070;margin:10px 0;">农事图片:</div> |
|||
<div class="imgs"> |
|||
<van-image |
|||
v-for="(v1,k1) in v.pic" :key="k1" |
|||
radius="4" |
|||
fit="cover" |
|||
@click="preview(k1,v.pic)" |
|||
:style="{'--n':k1==2&&v.pic.length>3?`'${v.pic.length-2}'`:''}" |
|||
:src="`${host('imgurl')}/${v1}`"> |
|||
<template v-slot:loading> |
|||
<van-loading type="spinner" size="20" /> |
|||
</template> |
|||
</van-image> |
|||
</div> |
|||
</template> |
|||
<template v-if="v.remark"> |
|||
<div style="font-size:12px;color:#707070;margin:10px 0;">备注:</div> |
|||
<div class="remark">{{v?.remark}}</div> |
|||
</template> |
|||
<template v-if="v?.inputVos?.length>0"> |
|||
<div class="line"/> |
|||
<div class="title">投入品信息</div> |
|||
<table> |
|||
<tr> |
|||
<td><span style="display:inline-block;min-width:45px;">投入品</span></td> |
|||
<td><span style="display:inline-block;min-width:52px;">投入数量</span></td> |
|||
<td><span style="display:inline-block;width:63px;">采购日期</span></td> |
|||
<td><span>供应商</span></td> |
|||
</tr> |
|||
<tr v-for="(v1,k1) in v?.inputVos" :key="k1"> |
|||
<td>{{v1.goodsName}}</td><td>{{v1.reducedQuantity}}{{v1.unit}}</td><td>{{new Date(v1.inventoryDate).format('yyyy-MM-dd')}}</td><td>{{v1.supplier}}</td> |
|||
</tr> |
|||
</table> |
|||
</template> |
|||
</div> |
|||
</d-dialog> |
|||
</template> |
|||
<script setup> |
|||
import { computed, inject, onMounted, reactive, ref, shallowRef } from 'vue' |
|||
import dDialog from '../../dialog.vue' |
|||
import request,{host} from '@/config/request' |
|||
import {preview} from '@/config/utils' |
|||
|
|||
var props=defineProps({ |
|||
cubId:{ |
|||
type:String, |
|||
default:"", |
|||
} |
|||
}) |
|||
|
|||
var dialog=inject('dialog') |
|||
var toast=inject('Toast') |
|||
|
|||
var dialogDom=ref() |
|||
var list=shallowRef([]) |
|||
var searchVal=reactive({ |
|||
pageNo:1, |
|||
pageSize:4, |
|||
type:"process", |
|||
produceCode:window.location.search.match(/code=(\w+)/)?.[1], |
|||
companyId: window.location.search.match(/id=(\w+)/)?.[1], |
|||
|
|||
}) |
|||
var total=ref(0) |
|||
var loading=false |
|||
|
|||
async function search(){ |
|||
if(!loading && (total.value==0||list.value.length<total.value)){ |
|||
loading=true |
|||
var res=await request('/scancode/breed/queryMoreInfoByCode',{ |
|||
method:"post", |
|||
data:{ |
|||
...searchVal, |
|||
cubId: props.cubId, |
|||
} |
|||
}) |
|||
loading=false |
|||
if(res.statu){ |
|||
list.value=list.value.concat(res.data.data.map(v=>({ |
|||
...v, |
|||
pic:v.pic?.split?.(',')?.filter(v=>v)||[] |
|||
}))) |
|||
searchVal.pageNo++ |
|||
total.value=res.data.total |
|||
if(list.value.length==total.value)toast('加载完成!'); |
|||
}else{ |
|||
dialog({ |
|||
title:"提示", |
|||
message:res.msg||"获取种植管理失败!" |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
defineExpose({ |
|||
open(){ |
|||
dialogDom.value.open() |
|||
searchVal.pageNo=1 |
|||
list.value=[] |
|||
total.value=0 |
|||
search() |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,81 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.content{ |
|||
position:relative; |
|||
&+*{ |
|||
margin-top:20px; |
|||
} |
|||
&:not(.last):before{ |
|||
content:""; |
|||
position:absolute; |
|||
height:100%; |
|||
border-left:1px dashed #546FD6; |
|||
left:5px; |
|||
top:17px; |
|||
} |
|||
.title{ |
|||
margin-top:10px; |
|||
.name{ |
|||
color:#EE2746; |
|||
font-size:12px; |
|||
margin-left: auto; |
|||
} |
|||
} |
|||
.item{ |
|||
margin-left:20px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="妊娠登记信息" ref="foldDom" v-if="modelValue?.length>0"> |
|||
<div class="content" :class="{last:k>=modelValue.length-1}" v-for="(v,k) in (modelValue||[]).slice(0,2)" :key="k"> |
|||
<div class="title"> |
|||
{{new Date(v.inspectDate).format('yyyy-MM-dd')}} |
|||
</div> |
|||
<div class="item"> |
|||
<span>配种日期:</span> <span>{{new Date(v.matingDate).format('yyyy-MM-dd')}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>配种天数:</span> <span>{{v.matingDay||0}}天</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>孕检结果:</span> <span>{{v.pregnancyResult}}</span> |
|||
</div> |
|||
</div> |
|||
<div class="more" v-if="modelValue?.length>=2" @click="detailDom.open()">查看更多>></div> |
|||
<van-empty v-if="!modelValue?.length>0" description="暂无数据"/> |
|||
</fold> |
|||
<detailList |
|||
ref="detailDom" |
|||
title="妊娠登记信息" |
|||
type="pregnancy" |
|||
:head="['登记日期','配种日期','配种天数','孕检结果']"> |
|||
<template #default="{data}"> |
|||
<td><span>{{new Date(data.inspectDate).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{new Date(data.matingDate).format('yyyy-MM-dd')}}</span></td> |
|||
<td><span>{{data.matingDay||0}}</span></td> |
|||
<td><span>{{data.pregnancyResult||0}}</span></td> |
|||
</template> |
|||
</detailList> |
|||
</template> |
|||
<script setup> |
|||
import { nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
import detailList from './detailList.vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:[Array,Object], |
|||
default:null, |
|||
} |
|||
}) |
|||
|
|||
var detailDom=ref() |
|||
var foldDom=ref() |
|||
watch(()=>props.modelValue, n=>{ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh() |
|||
}) |
|||
}) |
|||
</script> |
@ -0,0 +1,74 @@ |
|||
<style lang="less" scoped> |
|||
.btns{ |
|||
position:absolute; |
|||
top:18px; |
|||
right:27px; |
|||
border-radius: 20px; |
|||
overflow: hidden; |
|||
background:#E7EDFD; |
|||
display: flex; |
|||
span{ |
|||
width:30px; |
|||
height:20px; |
|||
color:#999; |
|||
text-align: center; |
|||
line-height: 23px; |
|||
font-size:9px; |
|||
&.active{ |
|||
background:#546FD6; |
|||
color:#fff; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold sup="谱系关系" ref="foldEl" :isCollapse="false" v-if="modelValue.length>0"> |
|||
<div class="btns"> |
|||
<span :class="{active:type=='mather'}" @click="type='mather'">母辈</span> |
|||
<span :class="{active:type=='father'}" @click="type='father'">父辈</span> |
|||
</div> |
|||
<template v-if="data"> |
|||
<div style="color:#EE2746;font-weight:bold;font-size:22px;margin-top:10px;">{{data?.varietyName}}</div> |
|||
<div class="item"> |
|||
<span>编号:</span> <span>{{data?.num}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>出生日期:</span> <span>{{data?.birthDate||'/'}}</span> |
|||
</div> |
|||
<div class="line"> |
|||
<div class="item"> |
|||
<span>毛色:</span> <span>{{data?.color}}</span> |
|||
</div> |
|||
<div class="item"> |
|||
<span>生育时年龄:</span> <span>{{data?.childbearingAge||age}}岁</span> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<van-empty v-else description="暂无数据"/> |
|||
</fold> |
|||
</template> |
|||
<script setup> |
|||
import { computed, nextTick, onMounted, ref, watch } from 'vue' |
|||
import fold from '../fold.vue' |
|||
|
|||
var foldEl=ref("") |
|||
var type=ref("mather") |
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:Array, |
|||
default:()=>[] |
|||
}, |
|||
birth:{ |
|||
type:String, |
|||
default:"", |
|||
} |
|||
}) |
|||
|
|||
var data=computed(()=>props.modelValue.find(v=>v.relation==({father:'父辈',mather:'母辈'})[type.value])) |
|||
var age=computed(()=>data.value?.birthDate&&props.birth?new Date(props.birth).year()-new Date(data.value?.birthDate).year():0) |
|||
watch(data, ()=>{ |
|||
nextTick(()=>{ |
|||
foldEl.value?.refresh?.() |
|||
}) |
|||
},{immediate:true}) |
|||
</script> |
@ -0,0 +1,103 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
.item{ |
|||
position:relative; |
|||
flex-direction: column; |
|||
padding-left:20px; |
|||
&:before{ |
|||
content:""; |
|||
position:absolute; |
|||
left:0px; |
|||
top:0px; |
|||
flex-shrink: 0; |
|||
width:15px; |
|||
height:15px; |
|||
background:radial-gradient(#546FD6 3px,rgba(84, 110, 214, 0.3) 4px,rgba(84, 110, 214, 0.3) 7px,transparent 7.3px); |
|||
} |
|||
&:not(:last-child){ |
|||
padding-bottom:8px; |
|||
&:after{ |
|||
content:""; |
|||
position:absolute; |
|||
left:7px; |
|||
top:14px; |
|||
height:100%; |
|||
border-left:1px dashed #546FD6; |
|||
} |
|||
} |
|||
.date{ |
|||
color:#EE2746; |
|||
font-size:15px; |
|||
font-weight: 500; |
|||
} |
|||
table{ |
|||
margin-top:9px; |
|||
background:#F3F5FF; |
|||
border-radius: 8px; |
|||
font-size:12px; |
|||
text-align: center; |
|||
tr{ |
|||
&:first-child{ |
|||
td{ |
|||
color:#546FD6; |
|||
padding-top:9px; |
|||
} |
|||
} |
|||
&:last-child td{ |
|||
padding-bottom:9px; |
|||
} |
|||
td{ |
|||
padding:4px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<fold title="屠宰信息" ref="foldDom"> |
|||
<div class="item"> |
|||
<div class="date">2024-09-09 11:23</div> |
|||
<table> |
|||
<tr> |
|||
<td>名称</td> <td>类型</td> <td>重量</td> |
|||
</tr> |
|||
<tr> |
|||
<td>xxxxxx屠宰1234</td> <td>待宰圈出库</td> <td>3000kg</td> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
<div class="item"> |
|||
<div class="date">2024-09-09 11:23</div> |
|||
<table> |
|||
<tr> |
|||
<td>名称</td> <td>类型</td> <td>重量</td> |
|||
</tr> |
|||
<tr> |
|||
<td>xxxxxx屠宰1234</td> <td>待宰圈出库</td> <td>3000kg</td> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
</fold> |
|||
</template> |
|||
<script setup> |
|||
import fold from '../fold.vue' |
|||
import {host} from '@/config/request' |
|||
import { computed, nextTick, ref, watch } from 'vue' |
|||
|
|||
var props=defineProps({ |
|||
modelValue:{ |
|||
type:Object, |
|||
default:null |
|||
} |
|||
}) |
|||
|
|||
var foldDom=ref() |
|||
watch(()=>props.modelValue, n=>{ |
|||
if(n){ |
|||
nextTick(()=>{ |
|||
foldDom.value?.refresh?.() |
|||
}) |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,66 @@ |
|||
<style lang="less"> |
|||
.van-popup.sanqiDialog{ |
|||
width:calc(100% - 40px); |
|||
background-color:transparent; |
|||
background-image:linear-gradient(transparent 50px,var(--bg,#ebf0ff) 50px); |
|||
background-size:100% 100%; |
|||
border-radius: 0 0 8px 8px; |
|||
min-height: 340px; |
|||
max-height: 80%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
&>.title{ |
|||
flex-shrink: 0; |
|||
background-image:url("@/assets/phoneImg/dialog_head.png"); |
|||
background-size:100% 78px; |
|||
background-repeat: no-repeat; |
|||
height:78px; |
|||
color:#637adc; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size:26px; |
|||
padding-top:18px; |
|||
font-family: system-ui; |
|||
font-weight: bold; |
|||
text-shadow: 2px 2px 2px rgba(99, 121, 220, 0.6); |
|||
} |
|||
&>.content{ |
|||
overflow: auto; |
|||
padding:var(--p,15px); |
|||
flex-grow: 1; |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<teleport to="body"> |
|||
<van-popup class="sanqiDialog" v-bind="$attrs" v-model:show="show"> |
|||
<div class="title">{{title}}</div> |
|||
<div class="content" @scroll="scroll"> |
|||
<slot/> |
|||
</div> |
|||
</van-popup> |
|||
</teleport> |
|||
</template> |
|||
<script setup> |
|||
import { ref } from "vue"; |
|||
var props=defineProps({ |
|||
title:{ |
|||
type:String, |
|||
default:"" |
|||
} |
|||
}) |
|||
var emit=defineEmits() |
|||
|
|||
var show=ref(false) |
|||
function scroll(e){ |
|||
if(e.target.scrollHeight-e.target.scrollTop<=e.target.clientHeight+2){ |
|||
emit('scroll') |
|||
} |
|||
} |
|||
defineExpose({ |
|||
open(val={}){ |
|||
show.value=true |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,72 @@ |
|||
<style lang="less" scoped> |
|||
.card{ |
|||
&.sup .collapse{ |
|||
margin-top:-14px!important; |
|||
} |
|||
.collapse{ |
|||
&.show{ |
|||
&:before{ |
|||
transform: rotate(-90deg)!important; |
|||
} |
|||
} |
|||
} |
|||
&>.frame{ |
|||
overflow: hidden; |
|||
transition: all 0.4s; |
|||
&>div{ |
|||
border:0.1px solid transparent; |
|||
padding-bottom:2px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<div class="card" :class="{sup:!!sup}" v-bind="$attrs"> |
|||
<div :class="!!sup?'title':'tag'">{{title||sup}}</div> |
|||
<div v-if="isCollapse" class="collapse SY-youbian" :class="{show}" @click="show=!show">{{show?"折叠":'展开'}}</div> |
|||
<div class="frame" :style="{height:`${show?height:minHeight}px`}"> |
|||
<div ref="frame" :style="bodyStyle"> |
|||
<slot/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<template v-if="show"> |
|||
<slot name="extra"/> |
|||
</template> |
|||
</template> |
|||
<script setup> |
|||
import { nextTick, onMounted, ref } from "vue" |
|||
|
|||
var props=defineProps({ |
|||
title:{ |
|||
type:String, |
|||
default:"", |
|||
}, |
|||
sup:{ |
|||
type:String, |
|||
default:"", |
|||
}, |
|||
minHeight:{ |
|||
type:Number, |
|||
default: 0, |
|||
}, |
|||
bodyStyle:"", |
|||
isCollapse:{ |
|||
type:Boolean, |
|||
default:true |
|||
} |
|||
}) |
|||
var show=ref(true) |
|||
var frame=ref() |
|||
var height=ref(0) |
|||
onMounted(()=>{ |
|||
setTimeout(()=>{ |
|||
height.value=frame.value.clientHeight |
|||
},600) |
|||
}) |
|||
defineExpose({ |
|||
refresh(){ |
|||
height.value=frame.value.clientHeight |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,221 @@ |
|||
<style lang="less" scoped> |
|||
.container{ |
|||
font-size: 15px; |
|||
min-height: 100%; |
|||
background:radial-gradient(transparent 60px, #c9d3f5 60px, #c9d3f5 160px, transparent 160px),linear-gradient(to bottom,#e7edfd 800px,#798ce8); |
|||
background-position:-160px 250px,top center; |
|||
background-repeat: no-repeat; |
|||
background-size:320px 320px,100% 100%; |
|||
border:0.1px solid transparent; |
|||
&>.head{ |
|||
background-image:url('@/assets/phoneImg/head_banner.png'); |
|||
background-size:100% 100%; |
|||
height:235px; |
|||
position:relative; |
|||
img{ |
|||
position:absolute; |
|||
&.logo{ |
|||
width:28px; |
|||
object-fit: cover; |
|||
top:48px; |
|||
left:69px; |
|||
} |
|||
&.title{ |
|||
object-fit: cover; |
|||
width:200px; |
|||
top:85px; |
|||
left:119px; |
|||
} |
|||
} |
|||
} |
|||
&>.content{ |
|||
margin:25px 13px 20px; |
|||
background:#bad1f6; |
|||
border-radius: 10px; |
|||
border:0.1px solid transparent; |
|||
&:deep .card{ |
|||
border-radius: 8px; |
|||
margin:15px 13px; |
|||
position:relative; |
|||
&>.tag{ |
|||
min-width:140px; |
|||
color:#fff; |
|||
font-size:18px; |
|||
height:36px; |
|||
line-height: 36px; |
|||
padding:0 10px 0 20px; |
|||
background:#546fd6; |
|||
width:max-content; |
|||
border-radius: 40px 40px 40px 0; |
|||
position:absolute; |
|||
top:10px; |
|||
left:-15px; |
|||
&:before{ |
|||
content:""; |
|||
position:absolute; |
|||
border-left:11px solid #546fd6; |
|||
border-top:11px solid transparent; |
|||
border-right:11px solid transparent; |
|||
border-bottom:11px solid transparent; |
|||
transform: rotate(-45deg); |
|||
top:25.5px; |
|||
left:5px; |
|||
} |
|||
} |
|||
&>.collapse{ |
|||
color:#999; |
|||
font-size: 14px; |
|||
width:max-content; |
|||
display: flex; |
|||
align-items: center; |
|||
flex-direction: row-reverse; |
|||
margin:11px 0 11px auto; |
|||
&:before{ |
|||
transform: rotate(90deg); |
|||
} |
|||
} |
|||
.item{ |
|||
display: flex; |
|||
margin-top:15px; |
|||
&>span{ |
|||
font-size:12px; |
|||
&:first-child{ |
|||
color:#999; |
|||
margin-right:10px; |
|||
flex-shrink: 0; |
|||
} |
|||
&:nth-child(2){ |
|||
margin-left:auto; |
|||
&.left{ |
|||
margin-left:0; |
|||
} |
|||
} |
|||
} |
|||
&:not(.block)>span:nth-child(2){ |
|||
text-align: right; |
|||
} |
|||
&.block{ |
|||
flex-wrap: wrap; |
|||
} |
|||
} |
|||
.line{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
span:nth-child(2){ |
|||
margin-left:0; |
|||
} |
|||
} |
|||
.title{ |
|||
display: flex; |
|||
align-items: center; |
|||
&:before{ |
|||
content:""; |
|||
width:5px; |
|||
height:15px; |
|||
border-radius: 5px; |
|||
background:linear-gradient(to bottom,#4E79B0,#15356D); |
|||
margin-right:10px; |
|||
} |
|||
} |
|||
.imgs{ |
|||
display: flex; |
|||
align-items: center; |
|||
margin:10px -15px 0 0; |
|||
width:100%; |
|||
.van-image{ |
|||
height:var(--h,83px); |
|||
width:calc(100%/3 - 15px); |
|||
margin-right:15px; |
|||
border-radius: 5px; |
|||
position:relative; |
|||
&:before{ |
|||
content:var(--n); |
|||
position:absolute; |
|||
top:0; |
|||
left:0; |
|||
width:100%; |
|||
height:100%; |
|||
color:#fff; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background:rgba(0, 0, 0, 0.4); |
|||
z-index: 10; |
|||
} |
|||
} |
|||
} |
|||
.more{ |
|||
width:max-content; |
|||
color:#999; |
|||
font-size:12px; |
|||
margin:15px auto 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<div class="container"> |
|||
<div class="head"> |
|||
<img class="logo" src="@/assets/phoneImg/logo.png"/> |
|||
<img class="title" src="@/assets/phoneImg/animal_head_title.png"/> |
|||
</div> |
|||
<div class="content"> |
|||
<file :modelValue="data?.varietyVo" v-if="data?.varietyVo||data?.parentVos?.length"> |
|||
<relation :modelValue="data?.parentVos" :birth="data?.varietyVo?.birthDate"/> |
|||
</file> |
|||
<breedBase :modelValue="data?.breedBaseVo" v-if="data?.breedBaseVo||data?.processVo?.record>0||data?.detectVo?.length"> |
|||
<breedMana :modelValue="data?.processVo" :cubId="data?.cubId"/> |
|||
<checkInfo :modelValue="data?.detectVo"/> |
|||
</breedBase> |
|||
<growDevelop :modelValue="data?.growVos" v-if="data?.growVos?.length||data?.ultrasonicVos?.length||data?.matingVos?.length||data?.pregnancyVos?.length||data?.abortVos?.length||data?.calvingVos?.length"> |
|||
<test :modelValue="data?.ultrasonicVos"/> |
|||
<estrus :modelValue="data?.matingVos"/> |
|||
<pregnancy :modelValue="data?.pregnancyVos"/> |
|||
<abort :modelValue="data?.abortVos"/> |
|||
<calving :modelValue="data?.calvingVos"/> |
|||
</growDevelop> |
|||
<!-- <slaughter /> --> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup> |
|||
import file from './breed/file.vue' |
|||
import relation from './breed/relation.vue' |
|||
import breedBase from './breed/base.vue' |
|||
import breedMana from './breed/mana/index.vue' |
|||
import checkInfo from './breed/checkInfo.vue' |
|||
import growDevelop from './breed/growDevelop.vue' |
|||
import test from './breed/liveTest.vue' |
|||
import estrus from './breed/estrus.vue' |
|||
import pregnancy from './breed/pregnancy.vue' |
|||
import abort from './breed/abort.vue' |
|||
import calving from './breed/calving.vue' |
|||
import slaughter from './breed/slaughter.vue' |
|||
|
|||
import request from '@/config/request' |
|||
import { inject, onMounted, provide, ref, shallowRef } from 'vue' |
|||
|
|||
var dialog=inject('dialog') |
|||
|
|||
var data=shallowRef({}) |
|||
|
|||
onMounted(async()=>{ |
|||
var res=await request('/scancode/breed/queryScanInfoByCode',{ |
|||
params:{ |
|||
produceCode: window.location.search.match(/code=(\w+)/)?.[1], |
|||
companyId: window.location.search.match(/id=(\w+)/)?.[1], |
|||
} |
|||
}) |
|||
if(res.statu){ |
|||
data.value=res.data |
|||
}else{ |
|||
|
|||
dialog({ |
|||
title:"提示", |
|||
message:res.msg||"获取数据失败!" |
|||
}) |
|||
} |
|||
}) |
|||
</script> |
@ -0,0 +1,19 @@ |
|||
import { createApp } from 'vue' |
|||
import App from './index.vue' |
|||
import store from '@/store' |
|||
import regComponents from '@/components' |
|||
import {defineObj} from 'black-knight/lib/config/custom' |
|||
import {provise} from 'black-knight/lib/config/tools' |
|||
|
|||
import "@/assets/style/phone.less" |
|||
|
|||
// 全局引入按需引入UI库 vant
|
|||
import vant from '@/config/vant.js' |
|||
|
|||
var app=createApp(App) |
|||
app.use(store) |
|||
.use(regComponents) |
|||
.use(vant) |
|||
.provide('event',new provise()) |
|||
.provide('defineObj', defineObj) |
|||
.mount('#app') |
After Width: | Height: | Size: 569 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 452 KiB |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 4.5 MiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 496 KiB |
After Width: | Height: | Size: 583 KiB |
After Width: | Height: | Size: 691 KiB |
After Width: | Height: | Size: 2.7 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 366 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 724 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 405 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 7.7 KiB |
@ -0,0 +1,24 @@ |
|||
*, |
|||
*:before, |
|||
*:after { |
|||
box-sizing: border-box; |
|||
} |
|||
body { |
|||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif; |
|||
font-size: 14px; |
|||
line-height: 1.15; |
|||
color: @--color-text-primary; |
|||
background-color: #fff; |
|||
} |
|||
a { |
|||
color: mix(#fff, @--color-primary, 20%); |
|||
text-decoration: none; |
|||
&:focus, |
|||
&:hover { |
|||
color: @--color-primary; |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
img { |
|||
vertical-align: middle; |
|||
} |
@ -0,0 +1,153 @@ |
|||
@import url("variables.less"); |
|||
@import url("base.less"); |
|||
|
|||
@import url("//at.alicdn.com/t/c/font_4123466_lmg78ig5ndk.css"); |
|||
[class*=farm-]{ |
|||
font-family: "farmApp" !important; |
|||
font-size: 16px; |
|||
font-style: normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
@import url("//at.alicdn.com/t/c/font_4438850_1r4dec40of8.css"); |
|||
[class*=FG-]{ |
|||
font-family: "farmGateway" !important; |
|||
font-size: 16px; |
|||
font-style: normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
.over{ |
|||
overflow: hidden; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
} |
|||
.double-line { |
|||
word-break: break-all; |
|||
overflow: hidden; |
|||
display: -webkit-box; |
|||
-webkit-line-clamp: var(--n,2); |
|||
-webkit-box-orient: vertical; |
|||
} |
|||
|
|||
.el-image{ |
|||
div.load,div.imgError{ |
|||
height:100%; |
|||
width:100%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
&:after{ |
|||
content:""; |
|||
display: block; |
|||
max-width: 100px; |
|||
max-height: 100px; |
|||
height:100%; |
|||
width:100%; |
|||
background-size: contain; |
|||
background-repeat: no-repeat; |
|||
background-position:center; |
|||
} |
|||
} |
|||
div.load{ |
|||
background:#f1eaf2; |
|||
&:after{ |
|||
background-image: url("@/assets/img/load_1.gif"); |
|||
} |
|||
} |
|||
div.imgError{ |
|||
&:after{ |
|||
background-image: url("@/assets/img/dkds.png"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.el-table.suyuan{ |
|||
flex-grow: 1; |
|||
height: 1px; |
|||
--el-table-header-bg-color:#F6F9F8; |
|||
--el-fill-color-lighter:#F6F9F8; |
|||
--el-table-row-hover-bg-color:#8ccab5; |
|||
tr:hover>td.el-table__cell{ |
|||
--hover:var(--c); |
|||
color:#fff; |
|||
} |
|||
} |
|||
|
|||
.el-pagination__rightwrapper{ |
|||
flex:0; |
|||
} |
|||
|
|||
.tab{ |
|||
color:rgba(var(--c),1); |
|||
background:rgba(var(--c),0.1); |
|||
height:24px; |
|||
line-height: 24px; |
|||
padding:0 5px; |
|||
margin: 0 10px 10px 0; |
|||
display:inline-block; |
|||
border-radius: 4px; |
|||
} |
|||
.customBg{ |
|||
--el-button-bg-color:#63C2A2; |
|||
--el-button-hover-bg-color:rgba(99, 194, 162, 0.7); |
|||
--el-button-text-color:#fff; |
|||
--el-button-hover-text-color:#fff; |
|||
} |
|||
.el-form-item.form-inline{ |
|||
&>.el-form-item__content{ |
|||
flex-wrap:nowrap; |
|||
} |
|||
} |
|||
|
|||
.scrollContent{ |
|||
&>.el-scrollbar__wrap>.el-scrollbar__view{ |
|||
background:#fff; |
|||
padding:15px; |
|||
height:100%; |
|||
display:flex; |
|||
flex-direction: column; |
|||
&>.content{ |
|||
display:flex; |
|||
flex-wrap: wrap; |
|||
align-items: flex-start; |
|||
flex-grow: 1; |
|||
height: 1px; |
|||
&>div{ |
|||
height:calc(100%/2 - 20px); |
|||
display:flex; |
|||
flex-direction: column; |
|||
&>.el-image{ |
|||
flex-grow: 1; |
|||
height: 1px; |
|||
} |
|||
} |
|||
} |
|||
&>.el-pagination{ |
|||
justify-content: flex-end; |
|||
flex-shrink: 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* 页面切换动画 */ |
|||
.fade-transform-leave-active, |
|||
.fade-transform-enter-active { |
|||
transition: all .5s; |
|||
} |
|||
|
|||
.fade-transform-enter-from { |
|||
opacity: 0; |
|||
transform: translateX(-30px); |
|||
} |
|||
|
|||
.fade-transform-leave-to { |
|||
opacity: 0; |
|||
transform: translateX(30px); |
|||
} |
|||
|
|||
.el-empty{ |
|||
margin:auto; |
|||
} |
@ -0,0 +1,22 @@ |
|||
/** |
|||
* 站点变量 |
|||
* |
|||
* #1 重置element-ui组件, 请查阅_element-ui__variable-lookup.scss官方变量列表进行重置, 必须保证变量名一致才能生效! |
|||
* #2 站内变量 |
|||
*/ |
|||
|
|||
// ---------- #1 ---------- |
|||
@--color-primary: #17b3a3; |
|||
@--color-text-primary: #303133; |
|||
|
|||
|
|||
// ---------- #2 ---------- |
|||
// Navbar |
|||
@navbar--background-color: @--color-primary; |
|||
|
|||
// Sidebar |
|||
@sidebar--background-color-dark: #263238; |
|||
@sidebar--color-text-dark: #8a979e; |
|||
|
|||
// Content |
|||
@content--background-color: #f1f4f5; |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 678 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 620 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 991 B |
After Width: | Height: | Size: 749 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 902 B |
After Width: | Height: | Size: 690 B |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 1018 B |