This commit is contained in:
BinBin Song 2025-06-17 20:47:31 +08:00
parent f7f9f8042d
commit 69508f5256
11 changed files with 1228 additions and 461 deletions

View File

@ -25,7 +25,7 @@
<!--app-html--> <!--app-html-->
</div> </div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
// <!-- // -->
<script> <script>
// var _hmt = _hmt || [] // var _hmt = _hmt || []
// ;(function () { // ;(function () {

View File

@ -133,6 +133,13 @@
"style": { "style": {
"navigationBarTitleText": "修改密码" "navigationBarTitleText": "修改密码"
} }
},
{
"path" : "pages/messageNotification/messageNotification",
"style" :
{
"navigationBarTitleText" : "消息通知"
}
} }
], ],
"globalStyle": { "globalStyle": {

View File

@ -15,6 +15,7 @@ defineProps<{
}>() }>()
const handleToBooking = (item: Object) => { const handleToBooking = (item: Object) => {
console.log('点击了分类', JSON.stringify(item))
if (item.auth) { if (item.auth) {
const path = item.path const path = item.path
const url = `/pages/${path}/${path}` const url = `/pages/${path}/${path}`
@ -30,8 +31,16 @@ const handleToBooking = (item: Object) => {
<template v-if="list.length"> <template v-if="list.length">
<view class="category-item" hover-class="none" v-for="item in list" :key="item.path" <view class="category-item" hover-class="none" v-for="item in list" :key="item.path"
@click="handleToBooking(item)"> @click="handleToBooking(item)">
<image v-if="item.auth" class="icon" :src="item.imgUrl" mode="scaleToFill"></image>
<image v-else class="icon" :src="item.defaultImgUrl" mode="scaleToFill"></image> <view v-if="item.unReadCount>=0" class="center-msg">
<span class="msg-text">消息通知</span>
<text class="unread-badge" v-if="item.unReadCount>0">{{ item.unReadCount }}</text>
</view>
<view v-else >
<image v-if="item.auth" class="icon" :src="item.imgUrl" mode="scaleToFill"></image>
<image v-else class="icon" :src="item.defaultImgUrl" mode="scaleToFill"></image>
</view>
</view> </view>
</template> </template>
<view v-else class="empty-data"> <view v-else class="empty-data">
@ -42,4 +51,31 @@ const handleToBooking = (item: Object) => {
<style lang="scss"> <style lang="scss">
@import '../styles/category.scss'; @import '../styles/category.scss';
.center-msg {
position: relative;
width: 100%;
height: 240rpx;
display: flex;
justify-content: center;
align-items: center;
}
.msg-text {
font-size: 32rpx;
color: #333;
width: 100%;
text-align: center;
}
.unread-badge {
position: absolute;
top: 20rpx;
right: 28rpx;
background: #ff4d4f;
color: #fff;
border-radius: 20rpx;
padding: 0 12rpx;
font-size: 24rpx;
min-width: 32rpx;
text-align: center;
z-index: 1;
}
</style> </style>

View File

@ -1,103 +1,121 @@
<script setup lang="ts"> <script setup lang="ts">
import { onLoad, onShow } from '@dcloudio/uni-app' import { onLoad, onShow } from "@dcloudio/uni-app";
import { useLoginStore } from '@/stores/modules/login' import { useLoginStore } from "@/stores/modules/login";
import { computed, ref, reactive } from 'vue' import { computed, ref, reactive } from "vue";
import CustomNavbar from './components/CustomNavbar.vue' import CustomNavbar from "./components/CustomNavbar.vue";
import CategoryPanel from './components/CategoryPanel.vue' import CategoryPanel from "./components/CategoryPanel.vue";
import footRight from './components/footRight.vue' import footRight from "./components/footRight.vue";
import PageSkeleton from './components/PageSkeleton.vue' import PageSkeleton from "./components/PageSkeleton.vue";
import { getHomeCategoryAPI } from '@/services/home' import { getHomeCategoryAPI, getUnreadMessage } from "@/services/home";
// //
const categoryList = ref([ const categoryList = ref([
{ {
path: 'approveOrder', path: "approveOrder",
name: '订单批准', name: "订单批准",
auth: false, auth: false,
imgUrl: '/static/images/approveOrder.png', imgUrl: "/static/images/approveOrder.png",
defaultImgUrl: '/static/images/approveOrder-default.png', defaultImgUrl: "/static/images/approveOrder-default.png",
}, },
{ {
path: 'unqualifiedNotification', path: "unqualifiedNotification",
name: '品质异常通知', name: "品质异常通知",
auth: false, auth: false,
imgUrl: '/static/images/unqualifiedNotification.png', imgUrl: "/static/images/unqualifiedNotification.png",
defaultImgUrl: '/static/images/unqualifiedNotification-default.png', defaultImgUrl: "/static/images/unqualifiedNotification-default.png",
}, },
{ {
path: 'productionReport', path: "productionReport",
name: '生产报工', name: "生产报工",
auth: false, auth: false,
imgUrl: '/static/images/productionReport.png', imgUrl: "/static/images/productionReport.png",
defaultImgUrl: '/static/images/productionReport-default.png', defaultImgUrl: "/static/images/productionReport-default.png",
}, },
{ {
path: 'assembleReport', path: "assembleReport",
name: '装配报工', name: "装配报工",
auth: false, auth: false,
imgUrl: '/static/images/assembleReport.png', imgUrl: "/static/images/assembleReport.png",
defaultImgUrl: '/static/images/assembleReport-default.png', defaultImgUrl: "/static/images/assembleReport-default.png",
}, },
{ {
path: "pgMaster", path: "pgMaster",
name: "过程检报工", name: "过程检报工",
auth: true, auth: true,
imgUrl: "/static/images/guochengjian.png", imgUrl: "/static/images/guochengjian.png",
defaultImgUrl: "/static/images/assembleReport-default.png" defaultImgUrl: "/static/images/assembleReport-default.png",
}, },
{ {
path: "zjPgMaster", path: "zjPgMaster",
name: "终检报工", name: "终检报工",
auth: true, auth: true,
imgUrl: "/static/images/zhongjian.png", imgUrl: "/static/images/zhongjian.png",
defaultImgUrl: "/static/images/assembleReport-default.png" defaultImgUrl: "/static/images/assembleReport-default.png",
}, },
{ {
path: "moJuSheJiReport", path: "moJuSheJiReport",
name: "进度上报", name: "进度上报",
auth: true, auth: true,
imgUrl: "/static/images/mojusheji.png", imgUrl: "/static/images/mojusheji.png",
defaultImgUrl: "/static/images/assembleReport-default.png" defaultImgUrl: "/static/images/assembleReport-default.png",
}, },
]) {
const loginStore = useLoginStore() path: "messageNotification",
name: "消息通知",
auth: true,
imgUrl: "",
defaultImgUrl: "",
unReadCount: 0, //
},
]);
const loginStore = useLoginStore();
const isLogin = computed(() => { const isLogin = computed(() => {
const accessToken = loginStore.userInfo?.accessToken const accessToken = loginStore.userInfo?.accessToken;
const storage_token = uni.getStorageSync('storage_userInfo')?.accessToken const storage_token = uni.getStorageSync("storage_userInfo")?.accessToken;
return !!accessToken || !!storage_token return !!accessToken || !!storage_token;
}) });
// //
const isLoading = ref(false) const isLoading = ref(false);
// //
onShow(async() => { onShow(async () => {
if (isLogin.value) { if (isLogin.value) {
await getHomeCategory() await getHomeCategory();
} else { } else {
categoryList.value.forEach((e) => { categoryList.value.forEach((e) => {
e.auth = true e.auth = true;
}) });
} }
}) });
const getHomeCategory = async () => { const getHomeCategory = async () => {
isLoading.value = true isLoading.value = true;
const params = {}
const data = await getHomeCategoryAPI(params) const params = {};
const menus = data?.menus.find((e) => e.path == '/applet')?.children || [] const data = await getHomeCategoryAPI(params);
const menus = data?.menus.find((e) => e.path == "/applet")?.children || [];
if (menus.length) { if (menus.length) {
const arr = [] const arr = [];
categoryList.value.forEach((e) => { categoryList.value.forEach((e) => {
const target = menus.find((q) => q.path == e.path) const target = menus.find((q) => q.path == e.path);
e.auth = !!target e.auth = !!target;
}) });
}
const unReadCount = await getUnreadMessage();
//
const msgItem = categoryList.value.find(
(e) => e.path === "messageNotification"
);
if (msgItem) {
msgItem.unReadCount = unReadCount;
msgItem.auth=true
} }
if (loginStore.userInfo.userId) { if (loginStore.userInfo.userId) {
const obj = { const obj = {
...loginStore.userInfo, ...loginStore.userInfo,
nickname: data.user.nickname nickname: data.user.nickname,
} };
loginStore.setInfo(obj) loginStore.setInfo(obj);
} }
isLoading.value = false isLoading.value = false;
} };
</script> </script>
<template> <template>
<view class="viewport"> <view class="viewport">
@ -118,7 +136,7 @@ const getHomeCategory = async () => {
page { page {
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
background-color: #F8FAFD; background-color: #f8fafd;
} }
.viewport { .viewport {

View File

@ -0,0 +1,401 @@
<script setup lang="ts">
import { onMounted, computed, ref } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { getApproveOrderAPI, getMessage, read } from "@/services/approveOrder";
import { useLoginStore } from "@/stores/modules/login";
import { formatDate } from "@/utils/index";
const userStore = useLoginStore();
const dictInfo = userStore.dictInfo;
const propertyDictData =
dictInfo.filter((e) => e.dictType == "heli_project_property") || [];
//
const isFinish = ref(false);
//
const isTriggered = ref(false);
// porps
const props = defineProps<{
orderState: number;
}>();
//
const isLoading = ref(false);
//
const queryParams: Required<any> = {
pageNo: 1,
pageSize: 20,
status: props.orderState,
isSnapshot: 0,
};
const dataList = ref([]);
const getListData = async () => {
if (isLoading.value) return;
if (isFinish.value === true) {
return uni.showToast({ icon: "none", title: "没有更多数据~" });
}
isLoading.value = true;
const data = await getMessage(queryParams);
isLoading.value = false;
data.list.forEach((e) => {
const obj = propertyDictData.find((q) => q.value == e.property) || {};
e.property = obj?.label;
e.createTime = formatDate(e.createTime, "YYYY-MM-DD HH:mm:ss");
// e.projectStartTime = formatDate(e.projectStartTime, 'YYYY-MM-DD')
// e.projectEndTime = formatDate(e.projectEndTime, 'YYYY-MM-DD')
});
dataList.value.push(...data.list);
//
if (data.list.length < queryParams.pageSize) {
isFinish.value = true;
} else {
queryParams.pageNo++;
}
};
function handlerRead(id: any) {
isLoading.value = true;
read(id)
.then(() => {
isLoading.value = false;
onRefresherrefresh();
})
.catch((err) => {
isLoading.value = false;
});
}
onMounted(async () => {
console.log("props", props);
await getListData();
});
onShow(async () => {
isLoading.value = false;
queryParams.pageNo = 1;
dataList.value = [];
isFinish.value = false;
await getListData();
});
const handleDetail = (id) => {
const url = `/pages/approveOrder/approveOrder-detail?id=${id}`;
uni.navigateTo({ url });
};
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true;
//
queryParams.pageNo = 1;
dataList.value = [];
isFinish.value = false;
//
await getListData();
//
isTriggered.value = false;
};
// const searchVal = ref('')
// const handleSearch = async () => {
// let dataListDefault = []
// const code = searchVal.value
// if (code) {
// dataListDefault = dataList.value
// dataList.value = dataList.value.filter((e) => {
// return e.code == code
// })
// } else {
// dataList.value = dataListDefault
// }
// }
</script>
<template>
<view class="cont">
<!-- <view class="search" v-if="dataList.length > 5">
<view class="title"></view>
<input class="uni-input" v-model="searchVal" @change="handleSearch" placeholder="根据编号搜索" />
</view> -->
<scroll-view
enable-back-to-top
scroll-y
class="data-list"
refresher-enabled
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getListData"
>
<view class="item" v-for="item in dataList" :key="item.id">
<!-- 方案1: 使用 flex 布局推荐 -->
<view
class="hd"
style="
display: flex;
justify-content: space-between;
align-items: center;
"
>
<view style="display: flex; flex-direction: column">
<view class="statusLabel">{{ item.thingname }}</view>
<view
class="product-item"
style="margin: 0; color: #333; font-size: 22rpx"
>{{ item.createTime }}</view
>
</view>
<view
class="read-btn"
v-if="orderState == 0"
@click="handlerRead(item.id)"
>已读</view
>
</view>
<view class="md">
<view class="product-item"
>客户简称<span class="item-value">{{ item.attr6 }}</span></view
>
<view class="product-item"
>项目名称<span class="item-value">{{ item.attr7 }}</span></view
>
<view class="product-item"
>子项目名称<span class="item-value">{{ item.attr8 }}</span></view
>
<view class="product-item"
>备注内容<span class="item-value">{{ item.attr9 }}</span></view
>
</view>
</view>
<!-- 底部提示文字 -->
<view
class="loading-text"
:style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"
>
{{ isFinish ? "没有更多数据~" : "正在加载..." }}
</view>
</scroll-view>
</view>
</template>
<style lang="scss">
//
.search {
padding: 4rpx;
width: 80%;
margin: 30rpx auto;
.uni-input {
border: 1px solid #d1d6db;
height: 60rpx;
line-height: 60rpx;
padding: 4rpx 10rpx;
font-size: 32rpx;
border-radius: 6rpx;
}
}
.data-list {
height: 90vh;
.item {
position: relative;
padding: 20rpx 0;
margin: 20rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
.hd {
padding: 10rpx;
font-size: 28rpx;
display: flex;
align-items: center;
.statusLabel {
font-size: 28rpx;
font-weight: 500;
color: #333333;
margin-right: 20rpx;
}
.read-btn {
font-size: 24rpx;
padding: 6rpx 24rpx;
border: 1rpx solid #3775f6;
border-radius: 30rpx;
color: #3775f6;
background: #f7f8fa;
margin-left: auto;
}
}
.md {
position: relative;
padding: 10rpx;
min-height: 100rpx;
font-size: 28rpx;
border-top: 2rpx solid #f2f2f2;
.product-item {
margin: 20rpx 0;
display: flex;
font-size: 22rpx;
align-items: center;
color: #737d88;
.item-value {
color: #333;
}
}
}
&:last-child {
padding-bottom: 40rpx;
}
}
.status {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
color: #999;
margin-bottom: 15rpx;
.date {
color: #666;
flex: 1;
}
.primary {
color: #ff9240;
}
.icon-delete {
line-height: 1;
margin-left: 10rpx;
padding-left: 10rpx;
border-left: 1rpx solid #e3e3e3;
}
}
.goods {
display: flex;
margin-bottom: 20rpx;
.cover {
width: 170rpx;
height: 170rpx;
margin-right: 20rpx;
border-radius: 10rpx;
overflow: hidden;
position: relative;
.image {
width: 170rpx;
height: 170rpx;
}
}
.quantity {
position: absolute;
bottom: 0;
right: 0;
line-height: 1;
padding: 6rpx 4rpx 6rpx 8rpx;
font-size: 24rpx;
color: #fff;
border-radius: 10rpx 0 0 0;
background-color: rgba(0, 0, 0, 0.6);
}
.meta {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.name {
height: 80rpx;
font-size: 26rpx;
color: #444;
}
.type {
line-height: 1.8;
padding: 0 15rpx;
margin-top: 10rpx;
font-size: 24rpx;
align-self: flex-start;
border-radius: 4rpx;
color: #888;
background-color: #f7f7f8;
}
.more {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #333;
}
}
.payment {
display: flex;
justify-content: flex-end;
align-items: center;
line-height: 1;
padding: 20rpx 0;
text-align: right;
color: #999;
font-size: 28rpx;
border-bottom: 1rpx solid #eee;
.quantity {
font-size: 24rpx;
margin-right: 16rpx;
}
.amount {
color: #444;
margin-left: 6rpx;
}
.symbol {
font-size: 20rpx;
}
}
.action {
display: flex;
justify-content: flex-end;
align-items: center;
padding-top: 20rpx;
.button {
width: 180rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx;
border-radius: 60rpx;
border: 1rpx solid #ccc;
font-size: 26rpx;
color: #444;
}
.secondary {
color: #3775f6;
border-color: #3775f6;
}
.primary {
color: #fff;
background-color: #3775f6;
border-color: #3775f6;
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
}
</style>import type { stringify } from 'querystring';

View File

@ -0,0 +1,38 @@
<template>
<view>
<web-view :src="showUrl" />
</view>
</template>
<script>
import { ref, onMounted, onUnmounted } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
export default {
setup() {
const showUrl = ref('');
// 使 onLoad
onLoad((options) => {
console.log('页面加载中...');
console.log(options.fileUrl);
if (options.fileUrl) {
showUrl.value = `https://star.hz-hl.com/FileServer/onlinePreview?url=${options.fileUrl}`;
console.log(showUrl.value);
}
});
// 使 onMounted onLoad
onMounted(() => {
console.log('Vue 组件挂载完成');
});
return {
showUrl,
};
},
};
</script>
<style scoped>
/* 你的样式 */
</style>

View File

@ -0,0 +1,150 @@
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import dataItem from './components/dataItem.vue'
// tabs
const orderTabs = ref([
{ status: 0, title: '未读', isRender: false },
{ status: 1, title: '已读', isRender: false },
])
//
const activeIndex = ref(0)
const handleIndexChange = (index: any) => {
orderTabs.value.forEach((e) => {
e.isRender = false
})
activeIndex.value = index
orderTabs.value[index].isRender = true
}
onLoad(async (options) => {
orderTabs.value.forEach((e, index) => {
e.isRender = e.status ==0
if (e.isRender) {
activeIndex.value = index
}
})
})
</script>
<template>
<view class="viewport">
<view class="tabs">
<text
class="item"
:class="{ active: activeIndex == index }"
v-for="(item, index) in orderTabs"
:key="item.title"
@tap="handleIndexChange(index)"
>
{{ item.title }}
</text>
<!-- 游标 -->
<view class="cursor" :style="{ left: activeIndex ? '65%' : '14%' }"></view>
</view>
<!-- 滑动容器 -->
<swiper
class="swiper"
:current="activeIndex"
@change="handleIndexChange($event.detail.current)"
>
<!-- 滑动项 -->
<swiper-item v-for="item in orderTabs" :key="item.title">
<dataItem v-if="item.isRender" :order-state="item.status" />
</swiper-item>
</swiper>
</view>
</template>
<style lang="scss">
page {
height: 100%;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
// background-color: #3775F6;
.navbar {
width: 750rpx;
color: #000;
position: fixed;
top: 0;
left: 0;
z-index: 9;
/* background-color: #f8f8f8; */
background-color: #3775f6;
.wrap {
position: relative;
background-color: #3775f6;
.title {
height: 44px;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
/* color: #000; */
color: #fff;
}
.back {
position: absolute;
left: 0;
height: 44px;
width: 44px;
font-size: 44rpx;
display: flex;
align-items: center;
justify-content: center;
/* color: #000; */
color: #fff;
}
}
}
.tabs {
display: flex;
justify-content: space-around;
line-height: 60rpx;
position: relative;
z-index: 9;
width: 100%;
.item {
flex: 1;
text-align: center;
padding: 20rpx;
font-size: 28rpx;
color: #1D2129;
&.active {
color: #356899;
}
}
.cursor {
position: absolute;
left: 13%;
bottom: 0;
width: 20%;
height: 6rpx;
padding: 0 50rpx;
background-color: #356899;
/* 过渡效果 */
transition: all 0.4s;
}
}
// swiper
.swiper {
background-color: #f7f7f8;
}
}
</style>

View File

@ -1,206 +1,299 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, computed, ref } from 'vue' import { onMounted, computed, ref } from "vue";
import { onLoad, onShow } from '@dcloudio/uni-app' import { onLoad, onShow } from "@dcloudio/uni-app";
import { getListAPI, getDictAPI, getListWxAPI, getTaskDetailAPI } from '@/services/productionReport' import {
import { useLoginStore } from '@/stores/modules/login' getListAPI,
import { formatDate } from '@/utils/index' getDictAPI,
getListWxAPI,
getTaskDetailAPI,
} from "@/services/productionReport";
import { useLoginStore } from "@/stores/modules/login";
import { formatDate } from "@/utils/index";
const userStore = useLoginStore() const userStore = useLoginStore();
const userId = userStore.userInfo.userId const userId = userStore.userInfo.userId;
// //
const isFinish = ref(false) const isFinish = ref(false);
// //
const isTriggered = ref(false) const isTriggered = ref(false);
// porps // porps
const props = defineProps<{ const props = defineProps<{
orderState : string orderState: string;
}>() }>();
const noticeMsg = ref('') const noticeMsg = ref("");
const isOverBeforeProcedure = async (id : number) => { const isOverBeforeProcedure = async (id: number) => {
//console.log(props.orderState) //console.log(props.orderState)
const params = { const params = {
id, id,
} };
const data = await getTaskDetailAPI(params) const data = await getTaskDetailAPI(params);
console.log(data.testYn) console.log(data.testYn);
if (data.beforeProcedureStatus == 0) { if (data.beforeProcedureStatus == 0) {
// //
noticeMsg.value = '上一道工序尚未完成报工!'; noticeMsg.value = "上一道工序尚未完成报工!";
return true; return true;
}else { } else {
return false; return false;
} }
} };
const statusText = computed(() => { const statusText = computed(() => {
const text = props.orderState == '0,1' ? '处理' : '查看' const text = props.orderState == "0,1" ? "处理" : "查看";
return text return text;
}) });
// //
const isLoading = ref(false) const isLoading = ref(false);
// //
const queryParams : Required<any> = { const queryParams: Required<any> = {
pageNo: 1, pageNo: 1,
pageSize: 5, pageSize: 5,
owner: userId, // owner: userId, //
procedureStatusList: props.orderState, // procedureStatusList: props.orderState, //
dispatchType: 'PRODUCTION', // dispatchType: "PRODUCTION", //
isReport: 1, // isReport: 1, //
//20250601/ //20250601/
subOrDetailName:'', subOrDetailName: "",
} };
const dataList = ref([]) const dataList = ref([]);
const getListData = async () => { const getListData = async () => {
if(props.orderState == '2'){ if (props.orderState == "2") {
queryParams.subOrDetailName = ''; queryParams.subOrDetailName = "";
} }
// 退 // 退
if (isLoading.value) return if (isLoading.value) return;
if (isFinish.value === true) { if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' }) return uni.showToast({ icon: "none", title: "没有更多数据~" });
} }
isLoading.value = true isLoading.value = true;
// //
// const data = await getListAPI(queryParams) // const data = await getListAPI(queryParams)
const data = await getListWxAPI(queryParams) const data = await getListWxAPI(queryParams);
isLoading.value = false isLoading.value = false;
data.list.forEach((e) => { data.list.forEach((e) => {
e.orderTime = formatDate(e.orderTime, 'YYYY-MM-DD') e.orderTime = formatDate(e.orderTime, "YYYY-MM-DD");
e.startTime = formatDate(e.startTime, 'YYYY-MM-DD') e.startTime = formatDate(e.startTime, "YYYY-MM-DD");
e.endTime = formatDate(e.endTime, 'YYYY-MM-DD') e.endTime = formatDate(e.endTime, "YYYY-MM-DD");
}) });
// //
dataList.value.push(...data.list) dataList.value.push(...data.list);
// //
if (queryParams.pageNo < data.total) { if (queryParams.pageNo < data.total) {
// //
queryParams.pageNo++ queryParams.pageNo++;
} else { } else {
// //
isFinish.value = true isFinish.value = true;
} }
} };
const todayStr = ref(''); const todayStr = ref("");
onMounted(async () => { onMounted(async () => {
const today = new Date(); const today = new Date();
const year = today.getFullYear(); const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0'); const month = String(today.getMonth() + 1).padStart(2, "0");
const day = String(today.getDate()).padStart(2, '0'); const day = String(today.getDate()).padStart(2, "0");
todayStr.value = `${year}-${month}-${day}`; todayStr.value = `${year}-${month}-${day}`;
await getListData() await getListData();
}) });
onShow(async () => { onShow(async () => {
isFinish.value = false isFinish.value = false;
isLoading.value = false isLoading.value = false;
queryParams.pageNo = 1 queryParams.pageNo = 1;
dataList.value = [] dataList.value = [];
await getListData() await getListData();
}) });
const handleDetail = async (item) => { const handleDetail = async (item) => {
var isoverBefore = await isOverBeforeProcedure(item.id); var isoverBefore = await isOverBeforeProcedure(item.id);
if (isoverBefore == true) { if (isoverBefore == true) {
uni.showToast({ uni.showToast({
title: noticeMsg.value, title: noticeMsg.value,
icon: 'none', icon: "none",
duration: 2000, duration: 2000,
}) });
return return;
} }
const url = `/pages/productionReport/productionReport-detail?id=${item.id}` const url = `/pages/productionReport/productionReport-detail?id=${item.id}`;
uni.navigateTo({ url }) uni.navigateTo({ url });
} };
// //
const onRefresherrefresh = async () => { const onRefresherrefresh = async () => {
// //
isTriggered.value = true isTriggered.value = true;
// //
queryParams.pageNo = 1 queryParams.pageNo = 1;
dataList.value = [] dataList.value = [];
isFinish.value = false isFinish.value = false;
// //
await getListData() await getListData();
// //
isTriggered.value = false isTriggered.value = false;
} };
const searchVal = ref('') const searchVal = ref("");
// const dataListDefault = ref([]) // const dataListDefault = ref([])
const handleSearch = async (e) => { const handleSearch = async (e) => {
queryParams.subOrDetailName = e.inputValue;
queryParams.pageNo = 1;
isFinish.value = false;
dataList.value = [];
await getListData();
};
queryParams.subOrDetailName = e.inputValue;
queryParams.pageNo = 1;
isFinish.value = false;
dataList.value = []
await getListData()
}
const handleScan = () => {
uni.scanCode({
success: (res) => {
searchVal.value = res.result
handleSearch({ inputValue: res.result })
},
fail: () => {
uni.showToast({ title: '扫码失败', icon: 'none' })
}
})
}
</script> </script>
<template> <template>
<view class="cont"> <view class="cont">
<view class="search" v-if="props.orderState == '0,1' "> <!-- <view class="search" v-if="props.orderState == '0,1' ">
<spring-search-box :showScan="true" :showReset="true" bgColor="#E2F3FF" @input="(e) => handleSearch(e)" placeholderColor="#28A0F8" searchColor="#28A0F8" v-model="searchVal" :mode="3" @change="(e) => handleSearch(e)" placeholder="请输入项目或子项目名称" clearable></spring-search-box> <spring-search-box :showScan="true" :showReset="true" bgColor="#E2F3FF" @input="(e) => handleSearch(e)" placeholderColor="#28A0F8" searchColor="#28A0F8" v-model="searchVal" :mode="3" @change="(e) => handleSearch(e)" placeholder="请输入项目或子项目名称" clearable></spring-search-box>
<!-- <spring-search-box :showScan="true" :showReset="true" bgColor="#E2F3FF" @input="(e) => handleSearch(e)" placeholderColor="#28A0F8" searchColor="#28A0F8" v-model="searchVal" :mode="3" @change="(e) => handleSearch(e)" placeholder="请输入项目或子项目名称"></spring-search-box --> </view> -->
<!-- <input class="uni-input" v-model="searchVal" placeholder="请输入项目或子项目名称" /> <view class="search" v-if="props.orderState == '0,1'">
<button><uni-icons type="search" size="30" class="icons" @click="handleSearch"></uni-icons></button> --> <view
</view> style="
<scroll-view enable-back-to-top scroll-y class="data-list" refresher-enabled :refresher-triggered="isTriggered" width: 100%;
@refresherrefresh="onRefresherrefresh" @scrolltolower="getListData"> display: flex;
<view class="item" v-for="item in dataList" :key="item.id" @click="handleDetail(item)"> align-items: center;
<view class="hd"> background: #e2f3ff;
<view class="num">派工单</view> border-radius: 20rpx;
<view class="statusLabel">{{ '(单号:'+ item.dispatchCode+') '}}</view> padding: 0 8rpx;
<view class="num">{{ '下工序:'+ (item.nextProcedureName == null ? '无':item.nextProcedureName)}}</view> height: 50px;
<!-- <view class="statusLabel " ></view> --> "
</view> >
<view class="md"> <input
<view class="product-item">项目名称{{ item.projectCode + ' ' + item.projectName }}</view> class="uni-input"
<view class="product-item">子项目{{ item.projectSubCode || '' }} {{' ' + item.projectSubName }}</view> v-model="searchVal"
<view class="product-row"> placeholder="请输入项目或子项目名称"
<view class="row-item"> :placeholder-style="'color:#28A0F8;'"
<view class="label">零件名称: {{ item.materialName }}</view> style="
</view> flex: 1;
<view class="row-item"> background: transparent;
<view class="label">派工工序: {{ item.procedureName }}</view> border: none;
</view> outline: none;
</view> font-size: 25rpx;
<view class="product-row"> color: #28a0f8;
<view class="row-item"> height: 50px;
<view class="label">派工数量</view> line-height: 50px;
<view class="val">{{ item.amount }}</view> "
</view> @input="handleSearch({ inputValue: searchVal })"
<view class="row-item"> clearable
<view class="label">总报工数量</view> />
<view class="val high-color">{{ item.totalReportAmount }}</view> <view
</view> style="
</view> background: none;
<view class="product-row"> border: none;
<view class="row-item"> padding: 0 10rpx;
<view class="label">预计工时</view> height: 50px;
<view class="val">{{ item.workTime }}</view> display: flex;
</view> align-items: center;
<view class="row-item"> "
<view class="label">总报工工时</view> @click="handleScan"
<view class="val high-color">{{ item.totalWorkTime }}</view> >
</view> <uni-icons type="scan" size="28" color="#28A0F8"></uni-icons>
</view> </view>
<view class="product-item" :style=" (item.endTime < todayStr)&&props.orderState != '2' ? 'color:red':null">预计生产日期{{ item.startTime }} {{ item.endTime }}</view> </view>
</view> </view>
<view class="statusText">{{ statusText }}</view> <scroll-view
</view> enable-back-to-top
<!-- 底部提示文字 --> scroll-y
<view class="loading-text" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"> class="data-list"
{{ isFinish ? '没有更多数据~' : '正在加载...' }} refresher-enabled
</view> :refresher-triggered="isTriggered"
</scroll-view> @refresherrefresh="onRefresherrefresh"
</view> @scrolltolower="getListData"
>
<view
class="item"
v-for="item in dataList"
:key="item.id"
@click="handleDetail(item)"
>
<view class="hd">
<view class="num">派工单</view>
<view class="statusLabel">{{
"(单号:" + item.dispatchCode + ") "
}}</view>
<view class="num">{{
"下工序:" +
(item.nextProcedureName == null ? "无" : item.nextProcedureName)
}}</view>
<!-- <view class="statusLabel " ></view> -->
</view>
<view class="md">
<view class="product-item"
>项目名称{{ item.projectCode + " " + item.projectName }}</view
>
<view class="product-item"
>子项目{{ item.projectSubCode || "" }}
{{ " " + item.projectSubName }}</view
>
<view class="product-row">
<view class="row-item">
<view class="label">零件名称: {{ item.materialName }}</view>
</view>
<view class="row-item">
<view class="label">派工工序: {{ item.procedureName }}</view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">派工数量</view>
<view class="val">{{ item.amount }}</view>
</view>
<view class="row-item">
<view class="label">总报工数量</view>
<view class="val high-color">{{ item.totalReportAmount }}</view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">预计工时</view>
<view class="val">{{ item.workTime }}</view>
</view>
<view class="row-item">
<view class="label">总报工工时</view>
<view class="val high-color">{{ item.totalWorkTime }}</view>
</view>
</view>
<view
class="product-item"
:style="
item.endTime < todayStr && props.orderState != '2'
? 'color:red'
: null
"
>预计生产日期{{ item.startTime }} {{ item.endTime }}</view
>
</view>
<view class="statusText">{{ statusText }}</view>
</view>
<!-- 底部提示文字 -->
<view
class="loading-text"
:style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"
>
{{ isFinish ? "没有更多数据~" : "正在加载..." }}
</view>
</scroll-view>
</view>
</template> </template>
<style lang="scss"> <style lang="scss">
// //
.search { .search {
padding: 0rpx; padding: 0rpx;
width: 90%; width: 90%;
@ -223,237 +316,236 @@
} }
} }
.data-list { .data-list {
height: 90vh;
height: 90vh; .item {
position: relative;
padding: 20rpx 0;
margin: 20rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
.item { .hd {
position: relative; padding: 10rpx;
padding: 20rpx 0; font-size: 28rpx;
margin: 20rpx 20rpx; display: flex;
border-radius: 10rpx;
background-color: #fff;
.hd { .statusLabel {
padding: 10rpx; font-size: 24rpx;
font-size: 28rpx; color: #737d88;
display: flex; }
}
.statusLabel { .md {
font-size: 24rpx; position: relative;
color: #737D88; padding: 10rpx;
} min-height: 100rpx;
} font-size: 28rpx;
border-top: 2rpx solid #f2f2f2;
.md { .product-item {
position: relative; margin: 20rpx 0;
padding: 10rpx; display: flex;
min-height: 100rpx; align-items: center;
font-size: 28rpx; color: #737d88;
border-top: 2rpx solid #F2F2F2; }
.product-item { .product-row {
margin: 20rpx 0; margin: 20rpx 0;
display: flex; display: flex;
align-items: center; flex-direction: row;
color: #737D88 justify-content: space-between;
} color: #737d88;
.product-row { .row-item {
margin: 20rpx 0; flex: 1;
display: flex;
flex-direction: row;
justify-content: space-between;
color: #737D88;
.row-item { .label {
flex: 1; margin-bottom: 10rpx;
}
.label { .val {
margin-bottom: 10rpx; color: #1d2129;
}
.val { &.high-color {
color: #1D2129; color: #00b42a;
}
}
}
}
}
&.high-color { .statusText {
color: #00B42A position: absolute;
} right: 30rpx;
} top: 100rpx;
} border-radius: 10rpx;
font-size: 24rpx;
padding: 10rpx 30rpx;
border-radius: 10rpx;
font-size: 24rpx;
background: linear-gradient(149deg, #2dace6 4%, #356899 98%);
color: #fff;
}
} &:last-child {
} padding-bottom: 40rpx;
}
}
.statusText { .status {
position: absolute; display: flex;
right: 30rpx; align-items: center;
top: 100rpx; justify-content: space-between;
border-radius: 10rpx; font-size: 28rpx;
font-size: 24rpx; color: #999;
padding: 10rpx 30rpx; margin-bottom: 15rpx;
border-radius: 10rpx;
font-size: 24rpx;
background: linear-gradient(149deg, #2DACE6 4%, #356899 98%);
color: #fff;
}
&:last-child { .date {
padding-bottom: 40rpx; color: #666;
} flex: 1;
} }
.status { .primary {
display: flex; color: #ff9240;
align-items: center; }
justify-content: space-between;
font-size: 28rpx;
color: #999;
margin-bottom: 15rpx;
.date { .icon-delete {
color: #666; line-height: 1;
flex: 1; margin-left: 10rpx;
} padding-left: 10rpx;
border-left: 1rpx solid #e3e3e3;
}
}
.primary { .goods {
color: #ff9240; display: flex;
} margin-bottom: 20rpx;
.icon-delete { .cover {
line-height: 1; width: 170rpx;
margin-left: 10rpx; height: 170rpx;
padding-left: 10rpx; margin-right: 20rpx;
border-left: 1rpx solid #e3e3e3; border-radius: 10rpx;
} overflow: hidden;
} position: relative;
.goods { .image {
display: flex; width: 170rpx;
margin-bottom: 20rpx; height: 170rpx;
}
}
.cover { .quantity {
width: 170rpx; position: absolute;
height: 170rpx; bottom: 0;
margin-right: 20rpx; right: 0;
border-radius: 10rpx; line-height: 1;
overflow: hidden; padding: 6rpx 4rpx 6rpx 8rpx;
position: relative; font-size: 24rpx;
color: #fff;
border-radius: 10rpx 0 0 0;
background-color: rgba(0, 0, 0, 0.6);
}
.image { .meta {
width: 170rpx; flex: 1;
height: 170rpx; display: flex;
} flex-direction: column;
} justify-content: center;
}
.quantity { .name {
position: absolute; height: 80rpx;
bottom: 0; font-size: 26rpx;
right: 0; color: #444;
line-height: 1; }
padding: 6rpx 4rpx 6rpx 8rpx;
font-size: 24rpx;
color: #fff;
border-radius: 10rpx 0 0 0;
background-color: rgba(0, 0, 0, 0.6);
}
.meta { .type {
flex: 1; line-height: 1.8;
display: flex; padding: 0 15rpx;
flex-direction: column; margin-top: 10rpx;
justify-content: center; font-size: 24rpx;
} align-self: flex-start;
border-radius: 4rpx;
color: #888;
background-color: #f7f7f8;
}
.name { .more {
height: 80rpx; flex: 1;
font-size: 26rpx; display: flex;
color: #444; align-items: center;
} justify-content: center;
font-size: 22rpx;
color: #333;
}
}
.type { .payment {
line-height: 1.8; display: flex;
padding: 0 15rpx; justify-content: flex-end;
margin-top: 10rpx; align-items: center;
font-size: 24rpx; line-height: 1;
align-self: flex-start; padding: 20rpx 0;
border-radius: 4rpx; text-align: right;
color: #888; color: #999;
background-color: #f7f7f8; font-size: 28rpx;
} border-bottom: 1rpx solid #eee;
.more { .quantity {
flex: 1; font-size: 24rpx;
display: flex; margin-right: 16rpx;
align-items: center; }
justify-content: center;
font-size: 22rpx;
color: #333;
}
}
.payment { .amount {
display: flex; color: #444;
justify-content: flex-end; margin-left: 6rpx;
align-items: center; }
line-height: 1;
padding: 20rpx 0;
text-align: right;
color: #999;
font-size: 28rpx;
border-bottom: 1rpx solid #eee;
.quantity { .symbol {
font-size: 24rpx; font-size: 20rpx;
margin-right: 16rpx; }
} }
.amount { .action {
color: #444; display: flex;
margin-left: 6rpx; justify-content: flex-end;
} align-items: center;
padding-top: 20rpx;
.symbol { .button {
font-size: 20rpx; width: 180rpx;
} height: 60rpx;
} display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx;
border-radius: 60rpx;
border: 1rpx solid #ccc;
font-size: 26rpx;
color: #444;
}
.action { .secondary {
display: flex; color: #3775f6;
justify-content: flex-end; border-color: #3775f6;
align-items: center; }
padding-top: 20rpx;
.button { .primary {
width: 180rpx; color: #fff;
height: 60rpx; background-color: #3775f6;
display: flex; border-color: #3775f6;
justify-content: center; }
align-items: center; }
margin-left: 20rpx;
border-radius: 60rpx;
border: 1rpx solid #ccc;
font-size: 26rpx;
color: #444;
}
.secondary { .loading-text {
color: #3775F6; text-align: center;
border-color: #3775F6; font-size: 28rpx;
} color: #666;
padding: 20rpx 0;
}
}
.primary {
color: #fff;
background-color: #3775F6;
border-color: #3775F6;
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
}
</style>import type { stringify } from 'querystring'; </style>import type { stringify } from 'querystring';

View File

@ -8,6 +8,24 @@
*/ */
import { http } from '@/utils/http' import { http } from '@/utils/http'
export const getMessage = (data: Object) => {
return http<any[]>({
method: 'POST',
url: '/heli/bdgzsomthing/getMessage',
data,
})
}
export const read = (id:any) => {
return http<any[]>({
method: 'GET',
url: '/heli/bdgzsomthing/read?id=' + id,
data: {},
})
}
export const getApproveOrderAPI = (data: Object) => { export const getApproveOrderAPI = (data: Object) => {
return http<any[]>({ return http<any[]>({
method: 'GET', method: 'GET',

View File

@ -9,5 +9,5 @@
// export const serviceDomain = 'https://nxhs.cjyx.cc' // export const serviceDomain = 'https://nxhs.cjyx.cc'
// export const serviceDomain = 'https://star.hz-hl.com' // export const serviceDomain = 'https://star.hz-hl.com'
// export const serviceDomain = 'http://222.71.165.187:9010' // export const serviceDomain = 'http://222.71.165.187:9010'
export const serviceDomain = 'http://localhost:8080' // export const serviceDomain = 'http://localhost:8080'
// export const serviceDomain = 'https://nxhs.cjyx.cc' export const serviceDomain = 'https://nxhs.cjyx.cc'

View File

@ -17,3 +17,10 @@ export const getHomeCategoryAPI = () => {
url: '/system/auth/get-permission-info', url: '/system/auth/get-permission-info',
}) })
} }
export const getUnreadMessage = () => {
return http<CategoryItem[]>({
method: 'GET',
url: '/heli/bdgzsomthing/unreadMessage',
})
}