ckgl/pages/documentary/documentary.vue
2025-01-14 17:26:18 +08:00

770 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { getAction, postAction } from '../../common/http';
import { formatDate } from '../../utils/date';
import { onShow } from '@dcloudio/uni-app';
import { showToast } from 'vant';
const form = ref({} as any)
const dataItem = ref({ jcrq: formatDate(new Date()), yjccts: 5 } as any)
const list = ref([] as any[])
const factory = ref([] as any[])
const nameList = ref([] as any[])
onMounted(() => {
getAction('/fabric/info/all').then((res : any) => {
if (res.code === 200) {
res.data.forEach((l : any) => {
let itemMl = mlList.value.find(m => m.text === l.commodity)
if (itemMl) {
let itemMm = itemMl.children.find(m => m.value === l.momme)
if (itemMm) {
itemMm.children.push({ text: l.width + 'cm', value: l.width })
} else {
itemMl.children.push({
text: l.momme + 'mm',
value: l.momme,
children: [{ text: l.width + 'cm', value: l.width }]
})
}
} else {
mlList.value.push({
text: l.commodity,
value: l.commodity,
children: [{ text: l.momme + 'mm', value: l.momme, children: [{ text: l.width + 'cm', value: l.width }] }]
})
}
})
}
})
//所有用户名
getAction('/v1/user/getNames').then((res : any) => {
if (res.code === 200) {
nameList.value = res.data.map((l : any) => ({ value: l, text: l }))
}
})
//获取工厂
getAction('/factory').then((res : any) => {
if (res.code === 200) {
factory.value = res.data.map((l : any) => ({ text: l.name, value: l.name }))
}
})
})
onShow(() => {
list.value = []
init()
//用户信息
uni.getStorage({
key: 'info',
success(res) {
let data = JSON.parse(res.data)
dataItem.value.gdy = data.userName
},
fail: (err : any) => {
console.log(err);
}
})
})
const onClickLeft = () => {
history.back()
}
const total = ref(0)
const currentPage = ref(1)
const finished = ref(false)
const loading = ref(false);
//动态获取数据
const onLoad = () => {
if (list.value.length < total.value) {
currentPage.value++
init()
} else {
finished.value = true
}
};
function init() {
total.value = 0
getAction('/tracking', { page: currentPage.value, size: 10, ...form.value }).then((res : any) => {
if (res.code === 200) {
res.data.record.forEach((l : any) => {
let a=[]
l.logs.forEach((l:any)=>{
if(l.details.trackingLog){
a=a.concat(l.details.trackingLog)
}
a.push(l)
})
l={...l.trackingLog,logs:a}
if (isValidJSON(l.craftComment)) {
l.craftComment = JSON.parse(l.craftComment)
}
if (l.zt === '待进厂') {
l.zcts=0
l.butonColor = butonColor.value[0]
} else if (l.zt === '待出厂') {
l.jcrq=l.logs[0].details.form.czrq
l.ccrq=l.logs[0].details.form.yjccts?addDaysToDate(l.jcrq,Number(l.logs[0].details.form.yjccts)):''
l.zcts=dateDiffInDays(l.logs[0].createTime,new Date())
l.butonColor = butonColor.value[1]
} else if (l.zt === '已出厂') {
l.jcrq=l.logs[0].details.form.czrq
l.ccrq=l.logs[0].details.form.yjccts?addDaysToDate(l.jcrq,Number(l.logs[0].details.form.yjccts)):''
l.zcts=dateDiffInDays(l.logs[0].createTime,l.logs[l.logs.length-1].createTime)
l.butonColor = butonColor.value[2]
} else {
l.jcrq=l.logs[0].details.form.czrq
l.ccrq=l.logs[0].details.form.yjccts?addDaysToDate(l.jcrq,Number(l.logs[0].details.form.yjccts)):''
l.zcts=dateDiffInDays(l.logs[0].createTime,new Date())
l.butonColor = butonColor.value[getRandomIntInclusive(3, 14)]
}
list.value.push(l)
})
total.value += res.data.total * 1
loading.value = false;
finished.value = false
}
})
}
//日期差
function dateDiffInDays(date1:any, date2:any) {
// 将日期字符串转换为 Date 对象
const dt1 = new Date(date1);
const dt2 = new Date(date2);
// 计算时间差(以毫秒为单位)
const timeDifference = dt2 - dt1;
// 将时间差转换为天数
const daysDifference = timeDifference / (1000 * 3600 * 24);
// 返回绝对值,因为结果可能是负数,取决于哪个日期更早
return Math.abs(Math.round(daysDifference));
}
function addDaysToDate(date:any, days:any) {
// 将传入的 date 转换为 Date 对象
const result = new Date(date);
// 设置时间为0点以避免时区影响
result.setHours(0, 0, 0, 0);
// 增加天数
result.setDate(result.getDate() + days);
// 返回新的日期
return formatDate(result);
}
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; // 包括最大值
}
function isValidJSON(str : any) {
if (typeof str !== 'string') return false; // 确保输入是一个字符串
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
watch(form.value, () => {
list.value = []
init()
})
const showPicker = ref(false)
const typeData = ref()
const popuList = ref([] as any[])
//选择框事件
const choosePic = (type : any) => {
showPicker.value = true
typeData.value = type
}
//选择框确认
const pickerConfirm = (val : any) => {
form.value[typeData.value] = val.selectedValues[0]
showPickerCancel()
}
//取消
const showPickerCancel = () => {
showPicker.value = false
}
//弹窗开启事件
const handleOpen = () => {
if (typeData.value === 'factory') {
popuList.value = factory.value
} else if (typeData.value === 'zt') {
popuList.value = [{ text: '待进厂', value: '待进厂' }, { text: '进行中', value: '进行中' }, { text: '待出厂', value: '待出厂' }, { text: '已出厂', value: '已出厂' }]
} else {
popuList.value = nameList.value
}
}
//日期选择
const show = ref(false)
const dataType = ref('')
const chooseDate = (val : any) => {
show.value = true
dataType.value = val
}
const onConfirmDate = (val : any) => {
if (dataType.value == 'jcrq') {
dataItem.value[dataType.value] = formatDate(val)
} else {
form.value[dataType.value] = formatDate(val)
}
show.value = false
}
const pickerList = ref([])//面料数据
const pickerContainerList = ref([])
const showPickerList = ref(false)
const searchValue = ref('')//查询的值
const searchIndex = ref(0)//查询到的数组
const mlList = ref([])
//选择面料
const selectChoose = () => {
showPickerList.value = true
}
//面料开启
const mlmcOpen = () => {
pickerList.value = mlList.value
pickerContainerList.value = pickerList.value
searchValue.value = ''
}
//面料关闭
const pickerCancel = () => {
showPickerList.value = false
}
//搜索
const selectedValue = ref()
const getSeachList = () => {
searchIndex.value = 0
let reg = new RegExp(searchValue.value)
let arr = []
pickerList.value.forEach(l => {
if (reg.test(l.text)) {
arr.push(l)
}
})
pickerContainerList.value = arr
}
//向上选择
const upSearch = () => {
if (searchIndex.value === 0 && pickerContainerList.value.length) {
searchIndex.value = pickerContainerList.value.length - 1
selectedValue.value = [pickerContainerList.value[searchIndex.value].text]
} else if (pickerContainerList.value.length) {
searchIndex.value--
selectedValue.value = [pickerContainerList.value[searchIndex.value].text]
} else {
showToast('没有了!')
}
}
//向下选择
const downSearch = () => {
if (pickerContainerList.value.length) {
if (searchIndex.value === pickerContainerList.value.length) {
searchIndex.value = 0
selectedValue.value = [pickerContainerList.value[searchIndex.value].text]
} else {
searchIndex.value++
selectedValue.value = [pickerContainerList.value[searchIndex.value].text]
}
} else {
showToast('没有了!')
}
}
//搜索框输入
const timer = ref()
const searchTo = () => {
if (timer.value) {
clearTimeout(timer.value)
}
timer.value = setTimeout(() => {
getSeachList()
}, 800)
}
const onConfirm = (val : any) => {
form.value.fabric = val.selectedValues[2] + '/' + val.selectedValues[0] + val.selectedValues[1]
pickerCancel()
}
const butonColor = ref(['#611987', '#611987', '#e54077', '#63b911', '#036fb8', '#ff9e49', '#fa7cff', '#f39b77', '#4fcdff', '#e54077', '#036fb8', '#ffc404', '#63b911', '#9cdd1c', '#9cdd1c',])
const showDialog = ref(false)
const itemList = ref({} as any)
const submit = () => {
if (!dataItem.value.yjccts) return showToast('请填写预计出厂天数!')
let data = {
subId: itemList.value.subId,
trackingLogId: itemList.value.id,
details: {
zt: '等待',
list: [],
form: {
czrq:dataItem.value.jcrq,
yjccts:dataItem.value.yjccts,
gdy:dataItem.value.gdy,
},
},
}
postAction('/tracking', data).then((res : any) => {
if (res.code === 200) {
showDialog.value = false
itemList.value.zt='等待'
showToast('更新成功!')
}
})
}
//计算米数
const computing = (list:any) =>{
let total=list.reduce((accumulator:any, currentValue:any) => {
return accumulator + currentValue.ms*1;
}, 0);
return total
}
//工序详情
const toDetile = (item:any) =>{
if(item.zt==='待出厂'){
uni.navigateTo({
url:'./ex-factory?item='+JSON.stringify(item)
})
}else if(item.zt==='已出厂'){
uni.navigateTo({
url:'./history?item='+JSON.stringify(item)
})
}else if(item.zt==='待进厂'){
showDialog.value = true
itemList.value=item
}else{
uni.navigateTo({
url:'./detail?item='+JSON.stringify(item)
})
}
}
</script>
<template>
<view class="flex">
<van-nav-bar title="跟单系统" left-text="返回" left-arrow @click-left="onClickLeft" />
<van-cell-group inset style="display: flex;">
<van-field v-model="form.factory" name="选择工厂" label="选择工厂" colon class="bor" label-width="5em" readonly
@click="choosePic('factory')" />
</van-cell-group>
<van-cell-group inset style="display: flex;">
<van-field v-model="form.startDate" name="开始时间" label="开始时间" colon class="bor" label-width="5em" readonly
@click="chooseDate('startDate')" :rules="[{ required: true, message: '请填写' }]" />
<van-field v-model="form.endDate" name="截止时间" label="截止时间" colon class="bor" label-width="5em" readonly
@click="chooseDate('endDate')" />
</van-cell-group>
<van-cell-group inset style="display: flex;">
<van-field v-model="form.fabric" name="面料名称" label="面料名称" class="bor" colon label-width="5em" readonly
@click="selectChoose" />
<van-field v-model="form.makeUser" name="做单人员" label="做单人员" colon class="bor" label-width="5em" readonly
@click="choosePic('makeUser')" />
</van-cell-group>
<van-cell-group inset style="display: flex;">
<van-field v-model="form.color" name="颜色色号" label="颜色色号" colon class="bor-a" label-width="5em" />
<van-field v-model="form.belongTo" name="归属人员" label="归属人员" colon class="bor" label-width="5em" readonly
@click="choosePic('belongTo')" />
</van-cell-group>
<van-cell-group inset style="display: flex;">
<van-field v-model="form.sd" name="谁定" label="谁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;定" colon
class="bor-a" label-width="5em" />
<van-field v-model="form.zt" name="订单状态" label="订单状态" colon class="bor" label-width="5em" readonly
@click="choosePic('zt')" />
</van-cell-group>
<view class="grid-container">
<view class="grid-item">面料/颜色</view>
<view class="grid-item">谁定/做单人/归属人<br>匹数/米数</view>
<view class="grid-item">工艺/工艺要求</view>
<view class="grid-item">状态</view>
</view>
<view class="content">
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<template v-for="(item,index) in list" :key="index">
<view class="grid-container">
<view class="grid-item">
<view class="grid-container1">
<view :class="indexSecond===(item.mls.length-1)?'grid-item2':'grid-item1'"
v-for="(itemSecond,indexSecond) in item.mls" :key="indexSecond">
{{itemSecond.mz}}<br>{{itemSecond.sh}}
</view>
</view>
</view>
<view class="grid-item">
<view class="grid-container1">
<view :class="indexSecond===(item.mls.length-1)?'grid-item2':'grid-item1'"
v-for="(itemSecond,indexSecond) in item.mls" :key="indexSecond">
{{item.sd}}/{{item.makeUser}}/{{item.belongTo}}<br>{{itemSecond.xxs.length}}匹/{{computing(itemSecond.xxs)}}米
</view>
</view>
</view>
<view class="grid-item">
{{item.craft}}<br>{{item.craftCmt.name?item.craftCmt.name:''}}
</view>
<view class="grid-item">
<van-button :style="{backgroundColor: item.butonColor,color:'#fff'}"
@click="toDetile(item)">{{item.zt}}</van-button>
</view>
</view>
<view style="text-align: center;display: flex;align-items: center;justify-content: space-around;">
<p>在厂天数:{{item.zcts}}天</p>
<p>
进厂:{{item.jcrq}}
<br>
预计:{{item.ccrq}}
</p>
</view>
</template>
</van-list>
</view>
</view>
<van-dialog v-model:show="showDialog">
<view style="margin-top: 10rpx;">
<van-cell-group inset>
<van-field v-model="dataItem.gdy" name="跟单员" label="跟单员" colon readonly label-width="6.5em"
class="bor-n" label-align="right" />
<van-field v-model="dataItem.jcrq" name="进厂日期" label="进厂日期" colon label-width="6.5em" class="bor"
readonly @click="chooseDate('jcrq')" label-align="right" />
<van-field v-model="dataItem.yjccts" name="预计出厂天数" label="预计出厂天数" type="digit" colon label-width="6.5em"
class="bor-a" label-align="right" />
</van-cell-group>
</view>
<template #footer>
<view class="footer-button">
<van-button plain size="small" style="width: 25vw;" @click="showDialog=false">
取消
</van-button>
<van-button size="small" type="success" style="width: 25vw;" @click="submit">
提交
</van-button>
</view>
</template>
</van-dialog>
<!--选择框-->
<van-popup v-model:show="showPicker" round position="bottom" @open="handleOpen">
<van-picker show-toolbar :columns="popuList" @confirm="pickerConfirm" @cancel="showPickerCancel"
ref="pickerRef" />
</van-popup>
<van-calendar v-model:show="show" @confirm="onConfirmDate" :min-date="new Date(2010, 0, 1)"
:max-date="new Date(2050, 0, 31)" />
<!-- 面料选择框-->
<van-popup v-model:show="showPickerList" position="bottom" @open="mlmcOpen">
<view class="select-model">
<van-picker :columns="pickerContainerList" @cancel="pickerCancel" v-model="selectedValue"
@confirm="onConfirm" />
<view>
<view class="top-select">
<view class="confirm-select">
<p>请选择品种</p>
</view>
<view class="search-box">
<view>
<van-search placeholder="请输入品种名字" v-model="searchValue" label="面料搜索:" background="#ffffff"
@input="searchTo()" :clearable="false" />
</view>
<view class="flex-btn">
<button class="search-btn" @click="upSearch()">↑</button>
<button class="search-btn" @click="downSearch()"></button>
</view>
</view>
</view>
</view>
</view>
</van-popup>
</template>
<style lang="scss" scoped>
.flex {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
font-size: 24rpx;
overflow-y: hidden;
.van-nav-bar {
width: 100%;
}
.grid-container {
display: grid;
grid-template-columns: 1.5fr 2fr 1.5fr 1fr;
padding: 0 15rpx;
.grid-item {
border: 1px solid #f2f2f2;
display: flex;
flex-direction: column;
text-align: center;
align-items: center;
justify-content: center;
.grid-container1 {
display: grid;
grid-template-columns: repeat(1, 1fr);;
width: 100%;
height: 100%;
.grid-item2 {
display: flex;
white-space: pre-line;
align-items: center;
justify-content: center;
padding: 5rpx;
word-break: break-all;
display: -webkit-box; /*将对象转为弹性盒模型展示*/
-webkit-box-orient: vertical; /*设置弹性盒模型子元素的排列方式*/
overflow: hidden; /*超出隐藏*/
}
.grid-item1 {
border-bottom: 1px solid #f2f2f2;
display: flex;
align-items: center;
justify-content: center;
padding: 5rpx;
word-break: break-all;
display: -webkit-box; /*将对象转为弹性盒模型展示*/
-webkit-box-orient: vertical; /*设置弹性盒模型子元素的排列方式*/
overflow: hidden; /*超出隐藏*/
}
}
}
}
.content {
flex: 1;
overflow-y: scroll;
font-size: 24rpx;
}
}
::v-deep .van-cell {
padding: 5px !important;
}
::v-deep .van-field {
font-size: 16px;
}
.bor {
::v-deep .van-field__control {
border: 1px solid #d7d7d7;
text-align: center;
}
::v-deep .van-field__label {
margin: 0;
}
}
.bor-a {
::v-deep .van-field__control {
border-bottom: 1px solid #d7d7d7;
text-align: center;
}
::v-deep .van-field__label {
margin: 0;
}
}
::v-deep .van-button--normal {
padding: 5px 8px;
height: 30px;
font-size: 22rpx;
}
::v-deep .van-field__control {
text-align: center;
font-size: 16px;
}
.footer-button {
margin: 20rpx;
display: flex;
justify-content: space-around;
}
/*面料选择搜索框*/
.select-model {
position: relative;
}
.confirm-select {
width: 100%;
}
.confirm-select>p {
text-align: center;
}
.confirm-select>button {
border: none;
background-color: #ffffff;
color: #388aed;
margin: 10px 30px 0 0;
}
.top-select {
position: absolute;
top: 30px;
left: 0;
right: 0;
margin: auto;
z-index: 999;
}
::v-deep .select-model .van-picker__toolbar {
height: 66px;
align-items: flex-start;
/*justify-content: flex-end;*/
}
::v-deep .select-model .van-picker__cancel,
.select-model .van-picker__confirm {
height: 30px;
padding: 10px 16px 0;
}
.search-btn {
padding: 1px 8px;
border: none;
background-color: #388aed;
color: #ffffff;
margin-left: 5px;
height: 30px;
line-height: 25px;
}
.search-box {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding-top: 15px;
padding-bottom: 5px;
position: relative;
background-color: #fff;
}
.van-search {
background-color: #f7f7f8;
}
.ml-search-jump {
padding: 3px 10px;
background-color: #388aed;
color: #ffffff;
border: none;
margin-left: 10px;
}
.flex-btn {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
/*面料选择搜索框*/
.select-model {
position: relative;
}
.confirm-select {
width: 100%;
}
.confirm-select>p {
text-align: center;
}
.confirm-select>button {
border: none;
background-color: #ffffff;
color: #388aed;
margin: 10px 30px 0 0;
}
.top-select {
position: absolute;
top: 30px;
left: 0;
right: 0;
margin: auto;
z-index: 999;
}
::v-deep .select-model .van-picker__toolbar {
height: 66px;
align-items: flex-start;
/*justify-content: flex-end;*/
}
::v-deep .select-model .van-picker__cancel,
.select-model .van-picker__confirm {
height: 30px;
padding: 10px 16px 0;
}
.search-btn {
padding: 1px 8px;
border: none;
background-color: #388aed;
color: #ffffff;
margin-left: 5px;
height: 30px;
line-height: 25px;
}
.search-box {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding-top: 15px;
padding-bottom: 5px;
position: relative;
background-color: #fff;
}
.van-search {
background-color: #f7f7f8;
}
.ml-search-jump {
padding: 3px 10px;
background-color: #388aed;
color: #ffffff;
border: none;
margin-left: 10px;
}
.flex-btn {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
</style>