异常通知确认页面

This commit is contained in:
z 2025-07-12 20:15:57 +08:00
parent 5cce8ba539
commit 76ac334774
22 changed files with 2984 additions and 21 deletions

View File

@ -151,7 +151,7 @@ public class bdgzsomthingController {
BeanUtils.toBean(list, bdgzsomthingRespVO.class));
}
@Scheduled(fixedRate = 10800000)
// @Scheduled(fixedRate = 10800000)
public void scheduledTask() {
bdgzsomthingService.selectds();
}
@ -163,12 +163,12 @@ public class bdgzsomthingController {
// selectSafeStorageAndDeliverOneYear();
// bdgzsomthingService.selectds();
}
@Scheduled(cron = "0 0 2 * * ?")
// @Scheduled(cron = "0 0 2 * * ?")
public void selectHasPrice(){
bdgzsomthingService.selectHasPrice();
}
@Scheduled(cron = "0 0 0 * * ?")
// @Scheduled(cron = "0 0 0 * * ?")
public void selectSafeStorageAndDeliverOneYear(){bdgzsomthingService.selectSafeStorageAndDeliverOneYear();}
@PostMapping("/getMessage")
@Operation(summary = "小程序消息")

View File

@ -71,8 +71,8 @@ public class PurchaseOrderNoController {
@Operation(summary = "更新采购订单主")
@PreAuthorize("@ss.hasPermission('project:purchase-order-no:update')")
public CommonResult<Boolean> updatePurchaseOrderNo(@Valid @RequestBody PurchaseOrderNoSaveReqVO updateReqVO) {
purchaseOrderNoService.updatePurchaseOrderNo(updateReqVO);
return success(true);
return purchaseOrderNoService.updatePurchaseOrderNo(updateReqVO);
}
@DeleteMapping("/delete")

View File

@ -269,4 +269,48 @@ public class UnqualifiedNotificationController {
unqualifiedNotificationService.review(pageReqVO);
return success(true);
}
@GetMapping("/unqualifiedNotificationConfirmPageWx")
@Operation(summary = "获得品质异常通知单确认分页")
public CommonResult<PageResult<UnqualifiedNotificationDO>> unqualifiedNotificationConfirmPageWx(@Valid UnqualifiedNotificationPageReqVO pageReqVO) {
int i = (pageReqVO.getPageNo()-1) * pageReqVO.getPageSize();
pageReqVO.setPageNum(i);
PageResult<UnqualifiedNotificationDO> unqualifiedNotificationPage = unqualifiedNotificationService.unqualifiedNotificationConfirmPageWx(pageReqVO);
List<UnqualifiedNotificationDO> list = unqualifiedNotificationPage.getList();
if(CollUtil.isNotEmpty(list)){
for (UnqualifiedNotificationDO unqualifiedNotificationDO : list) {
List<String> fileUrlList = new ArrayList<>();
Integer type = 0;
if (unqualifiedNotificationDO.getTypeName().equals("过程检")){
type = 2;
}else if (unqualifiedNotificationDO.getTypeName().equals("终检")){
type = 1;
}
List<UnqualifiedNotificationFileDO> unqualifiedNotificationFileDOS = unqualifiedNotificationFileService.queryUnqualifiedNotificationFileBySuperId(unqualifiedNotificationDO.getId(),type);
if(CollUtil.isNotEmpty(unqualifiedNotificationFileDOS)){
for (UnqualifiedNotificationFileDO unqualifiedNotificationFileDO : unqualifiedNotificationFileDOS) {
fileUrlList.add(unqualifiedNotificationFileDO.getFileUrl());
}
unqualifiedNotificationDO.setFileUrlList(fileUrlList);
}
}
}
return success(unqualifiedNotificationPage);
}
@PostMapping("/confirm")
@Operation(summary = "确认品质异常通知单")
@OperateLog(enable = false)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Long> confirm(@Valid @RequestBody UnqualifiedNotificationSaveReqVO operateReqVO) {
unqualifiedNotificationService.confirm(operateReqVO);
return success(operateReqVO.getId());
}
@GetMapping("/countWx1")
@Operation(summary = "获得品质异常通知单确认消息")
@PreAuthorize("@ss.hasPermission('heli:unqualified-notification:query')")
public CommonResult<Long> countWx1(@Valid UnqualifiedNotificationPageReqVO pageReqVO) {
return success(unqualifiedNotificationService.countWx1(pageReqVO));
}
}

View File

@ -150,6 +150,8 @@ public class UnqualifiedNotificationDO extends BaseDO {
private Integer isRepre;
@TableField(exist = false)
private Integer isQua;
@TableField(exist = false)
private Integer conStatus;
public boolean canSave(){
return UnqualifiedNotificationStatusEnum.SAVE.getCode() == this.notificationStatus.intValue();
}

View File

@ -136,4 +136,12 @@ public interface UnqualifiedNotificationMapper extends BaseMapperX<UnqualifiedNo
}
List<QualityStatistics> QualityStatistics(@Param("page") Page<QualityStatistics> page, @Param("pageReqVO") UnqualifiedNotificationPageReqVO pageReqVO);
Long selectCountConfirmPageWx( @Param("queryType") Integer queryType,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
List<UnqualifiedNotificationDO> selectConfirmPageWx( @Param("queryType") Integer queryType,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
}

View File

@ -29,7 +29,7 @@ public interface PurchaseOrderNoService {
*
* @param updateReqVO 更新信息
*/
void updatePurchaseOrderNo(@Valid PurchaseOrderNoSaveReqVO updateReqVO);
CommonResult<Boolean> updatePurchaseOrderNo(@Valid PurchaseOrderNoSaveReqVO updateReqVO);
/**
* 删除采购订单主

View File

@ -32,6 +32,7 @@ import com.chanko.yunxi.mes.module.heli.service.purchaseordermakedetail.Purchase
import com.chanko.yunxi.mes.module.heli.service.serialnumber.SerialNumberService;
import com.chanko.yunxi.mes.module.system.api.user.AdminUserApi;
import com.chanko.yunxi.mes.module.system.dal.dataobject.user.AdminUserDO;
import com.chanko.yunxi.mes.module.system.enums.ErrorCodeConstants;
import com.chanko.yunxi.mes.module.system.service.user.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -112,7 +113,7 @@ public class PurchaseOrderNoServiceImpl implements PurchaseOrderNoService {
}
@Override
public void updatePurchaseOrderNo(PurchaseOrderNoSaveReqVO updateReqVO) {
public CommonResult<Boolean> updatePurchaseOrderNo(PurchaseOrderNoSaveReqVO updateReqVO) {
// 校验存在
validatePurchaseOrderNoExists(updateReqVO.getId());
// 更新
@ -130,7 +131,8 @@ public class PurchaseOrderNoServiceImpl implements PurchaseOrderNoService {
updateObj.setSubmitTime(currTime);
} else {
// 处理未找到审核人情况
throw new RuntimeException("审核人未找到");
// throw new RuntimeException("审核人未找到");
return CommonResult.error(400,"审核人未找到");
}
}else if(updateReqVO.getStatus()==2 && updateReqVO.getAuditor().equals(loginUser.getId())){
ShenheDO shenHeDOOne = shenheMapper.selectOne(ShenheDO::getShenheName,"1",ShenheDO::getShenheUser,updateReqVO.getAuditor());
@ -149,13 +151,16 @@ public class PurchaseOrderNoServiceImpl implements PurchaseOrderNoService {
orderYfService.createCg(orderYfVO);
}
} else {
throw new RuntimeException("采购订单审核失败,请联系管理员!");
// throw new RuntimeException("采购订单审核失败,请联系管理员!");
return CommonResult.error(400,"采购订单审核失败,请联系管理员!");
}
}
if(updateReqVO.getStatus()== 3){
pOrderReceivedCompleted(updateReqVO.getPurchaseNo(),updateReqVO.getId());
}
purchaseOrderNoMapper.updateById(updateObj);
return CommonResult.success(true);
}
private void pOrderReceivedCompleted(String purchaseNo,Long id) {
PurchaseOrderNoPageReqVO purchaseOrderPageReqVO = new PurchaseOrderNoPageReqVO();

View File

@ -55,10 +55,14 @@ public interface UnqualifiedNotificationService {
*/
PageResult<UnqualifiedNotificationDO> getUnqualifiedNotificationPage(UnqualifiedNotificationPageReqVO pageReqVO);
PageResult<UnqualifiedNotificationDO> getUnqualifiedNotificationPageWx(UnqualifiedNotificationPageReqVO pageReqVO);
PageResult<UnqualifiedNotificationDO> unqualifiedNotificationConfirmPageWx(UnqualifiedNotificationPageReqVO pageReqVO);
void operate(UnqualifiedNotificationSaveReqVO operateReqVO);
void operateWx(UnqualifiedNotificationSaveReqVO operateReqVO);
PageResult<QualityStatistics> getUnqualifiedNotificationStatisticPage(UnqualifiedNotificationPageReqVO pageReqVO);
void review(UnqualifiedNotificationPageReqVO pageReqVO);
void confirm(UnqualifiedNotificationSaveReqVO operateReqVO);
Long countWx1(UnqualifiedNotificationPageReqVO pageReqVO);
}

View File

@ -241,6 +241,21 @@ try {
pageResult.setList(unqualifiedNotificationDOS);
return pageResult;
}
@Override
public PageResult<UnqualifiedNotificationDO> unqualifiedNotificationConfirmPageWx(UnqualifiedNotificationPageReqVO pageReqVO) {
PageResult<UnqualifiedNotificationDO> pageResult = new PageResult<>();
Long total = unqualifiedNotificationMapper.selectCountConfirmPageWx(pageReqVO.getQueryType(), pageReqVO.getPageNum(), pageReqVO.getPageSize());
pageResult.setTotal(total);
if (total > 0L){
pageResult.setTotalPages(total.intValue()/ pageReqVO.getPageSize());
}
List<UnqualifiedNotificationDO> unqualifiedNotificationDOS = unqualifiedNotificationMapper.selectConfirmPageWx(pageReqVO.getQueryType(), pageReqVO.getPageNum(), pageReqVO.getPageSize());
pageResult.setList(unqualifiedNotificationDOS);
return pageResult;
}
@Override
public Long countWx(UnqualifiedNotificationPageReqVO pageReqVO) {
PageResult<UnqualifiedNotificationDO> pageResult = new PageResult<>();
@ -322,4 +337,25 @@ try {
}
}
@Override
public void confirm(UnqualifiedNotificationSaveReqVO operateReqVO) {
if ("过程检".equals(operateReqVO.getType())){
LambdaUpdateWrapper<BgMasterLineDO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(BgMasterLineDO::getId, operateReqVO.getId())
.set(BgMasterLineDO::getConStatus, 2);
bgMasterLineMapper.update( updateWrapper);
}else {
LambdaUpdateWrapper<ZjBgMasterLineDO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ZjBgMasterLineDO::getId, operateReqVO.getId())
.set(ZjBgMasterLineDO::getConStatus, 2);
zjBgMasterLineMapper.update( updateWrapper);
}
}
@Override
public Long countWx1(UnqualifiedNotificationPageReqVO pageReqVO) {
return unqualifiedNotificationMapper.selectCountConfirmPageWx(1, 5,5);
}
}

View File

@ -155,14 +155,17 @@
gh.createTime as createTime,gh.creatorName as creatorName,gh.projectSubCode as projectSubCode,
gh.projectName as projectName, gh.auditorName as auditorName,gh.auditOpinion as auditOpinion,
gh.auditTime as auditTime,gh.isRepre,gh.isQua,gh.notificationStatus as notificationStatus,
gh.remark as remark ,gh.materialName as materialName,gh.blueprintNo as blueprintNo, gh.procedureName as procedureName
gh.remark as remark ,gh.materialName as materialName,gh.blueprintNo as blueprintNo, gh.procedureName as procedureName,
gh.conStatus as conStatus
FROM (
SELECT t.id as id, g.pg_number as code, g.project_sub_name as projectSubName,
t.amount as amount, g.amount as totalAmount, '过程检' as typeName,
t.ent_time as createTime,u.nickname as creatorName,g.project_sub_number as projectSubCode,
g.project_name as projectName ,u2.nickname as auditorName,t.audit_opinion as auditOpinion,
t.audit_time as auditTime,t.is_repre as isRepre,t.is_qua as isQua,t.notification_status as notificationStatus,
t.remark as remark, g.material_name as materialName,g.blueprint_no as blueprintNo, pr1.name as procedureName
t.remark as remark, g.material_name as materialName,g.blueprint_no as blueprintNo, pr1.name as procedureName,
t.con_status as conStatus
FROM quality_bg_master_line t
LEFT JOIN quality_pg_master_line g ON t.zj_mx_id = g.id
LEFT JOIN base_procedure pr1 ON pr1.id = g.procedure_id
@ -177,7 +180,9 @@
zj.ent_time as createTime,u1.nickname as creatorName,g1.project_sub_number as projectSubCode,
g1.project_name as projectName , u3.nickname as auditorName,zj.audit_opinion as auditOpinion,
zj.audit_time as auditTime,zj.is_repre as isRepre,zj.is_qua as isQua,zj.notification_status as notificationStatus,
zj.remark as remark ,'' as materialName, '' as blueprintNo, '' as procedureName
zj.remark as remark ,'' as materialName, '' as blueprintNo, '' as procedureName,
zj.con_status as conStatus
FROM quality_zj_bg_master_line zj
LEFT JOIN quality_zj_pg_master_line g1 ON zj.zj_mx_id = g1.id and zj.is_qua = 1
left join system_users u1 on u1.id = zj.bg_user left join system_users u3 on u3.id = zj.auditor
@ -224,4 +229,87 @@
) gh
ORDER BY gh.createTime DESC LIMIT #{offset}, #{limit}
</select>
<select id="selectCountConfirmPageWx" parameterType="java.lang.Integer" resultType="java.lang.Long">
SELECT count(*) FROM (
SELECT t.id as id, g.pg_number as code, g.project_sub_name as projectSubName,
t.amount as amount, g.amount as totalAmount, '过程检' as typeName,
t.ent_time as createTime,u.nickname as creatorName,g.project_sub_number as projectSubCode,
g.project_name as projectName ,u2.nickname as auditorName,t.audit_opinion as auditOpinion,
t.audit_time as auditTime,t.is_repre as isRepre,t.is_qua as isQua,t.notification_status as notificationStatus,
t.remark as remark, g.material_name as materialName,g.blueprint_no as blueprintNo, pr1.name as procedureName,
t.con_status as conStatus
FROM quality_bg_master_line t
LEFT JOIN quality_pg_master_line g ON t.zj_mx_id = g.id
LEFT JOIN base_procedure pr1 ON pr1.id = g.procedure_id
left join system_users u on u.id = t.bg_user left join system_users u2 on u2.id = t.auditor
WHERE t.deleted = 0 AND t.tenant_id = 2 AND g.deleted = 0 AND g.tenant_id = 2
AND pr1.deleted = 0 AND pr1.tenant_id = 2 and t.is_qua = 1
AND t.notification_status =3
AND t.audit_opinion = 2
AND t.con_status = #{queryType}
UNION ALL
SELECT zj.id as id, g1.pg_number as code, g1.project_sub_name as projectSubName,
zj.amount as amount, g1.amount as totalAmount, '终检' as typeName,
zj.ent_time as createTime,u1.nickname as creatorName,g1.project_sub_number as projectSubCode,
g1.project_name as projectName , u3.nickname as auditorName,zj.audit_opinion as auditOpinion,
zj.audit_time as auditTime,zj.is_repre as isRepre,zj.is_qua as isQua,zj.notification_status as notificationStatus,
zj.remark as remark ,'' as materialName, '' as blueprintNo, '' as procedureName,
zj.con_status as conStatus
FROM quality_zj_bg_master_line zj
LEFT JOIN quality_zj_pg_master_line g1 ON zj.zj_mx_id = g1.id
left join system_users u1 on u1.id = zj.bg_user left join system_users u3 on u3.id = zj.auditor
WHERE zj.deleted = 0 AND zj.tenant_id = 2 AND g1.deleted = 0 AND g1.tenant_id = 2 and zj.is_qua = 1
AND zj.notification_status = 3
AND zj.audit_opinion=2
AND zj.con_status = #{queryType}
) gh
</select>
<select id="selectConfirmPageWx" parameterType="java.lang.Integer" resultType="com.chanko.yunxi.mes.module.heli.dal.dataobject.unqualifiednotification.UnqualifiedNotificationDO">
SELECT gh.id as id, gh.code as code, gh.projectSubName as projectSubName,
gh.amount as amount, gh.totalAmount as totalAmount, gh.typeName as typeName,
gh.createTime as createTime,gh.creatorName as creatorName,gh.projectSubCode as projectSubCode,
gh.projectName as projectName, gh.auditorName as auditorName,gh.auditOpinion as auditOpinion,
gh.auditTime as auditTime,gh.isRepre,gh.isQua,gh.notificationStatus as notificationStatus,
gh.remark as remark ,gh.materialName as materialName,gh.blueprintNo as blueprintNo, gh.procedureName as procedureName,
gh.conStatus as conStatus
FROM (
SELECT t.id as id, g.pg_number as code, g.project_sub_name as projectSubName,
t.amount as amount, g.amount as totalAmount, '过程检' as typeName,
t.ent_time as createTime,u.nickname as creatorName,g.project_sub_number as projectSubCode,
g.project_name as projectName ,u2.nickname as auditorName,t.audit_opinion as auditOpinion,
t.audit_time as auditTime,t.is_repre as isRepre,t.is_qua as isQua,t.notification_status as notificationStatus,
t.remark as remark, g.material_name as materialName,g.blueprint_no as blueprintNo, pr1.name as procedureName,
t.con_status as conStatus
FROM quality_bg_master_line t
LEFT JOIN quality_pg_master_line g ON t.zj_mx_id = g.id
LEFT JOIN base_procedure pr1 ON pr1.id = g.procedure_id
left join system_users u on u.id = t.bg_user left join system_users u2 on u2.id = t.auditor
WHERE t.deleted = 0 AND t.tenant_id = 2 AND g.deleted = 0 AND g.tenant_id = 2
AND pr1.deleted = 0 AND pr1.tenant_id = 2 and t.is_qua = 1
AND t.notification_status =3
AND t.audit_opinion = 2
AND t.con_status = #{queryType}
UNION ALL
SELECT zj.id as id, g1.pg_number as code, g1.project_sub_name as projectSubName,
zj.amount as amount, g1.amount as totalAmount, '终检' as typeName,
zj.ent_time as createTime,u1.nickname as creatorName,g1.project_sub_number as projectSubCode,
g1.project_name as projectName , u3.nickname as auditorName,zj.audit_opinion as auditOpinion,
zj.audit_time as auditTime,zj.is_repre as isRepre,zj.is_qua as isQua,zj.notification_status as notificationStatus,
zj.remark as remark ,'' as materialName, '' as blueprintNo, '' as procedureName,
zj.con_status as conStatus
FROM quality_zj_bg_master_line zj
LEFT JOIN quality_zj_pg_master_line g1 ON zj.zj_mx_id = g1.id
left join system_users u1 on u1.id = zj.bg_user left join system_users u3 on u3.id = zj.auditor
WHERE zj.deleted = 0 AND zj.tenant_id = 2 AND g1.deleted = 0 AND g1.tenant_id = 2 and zj.is_qua = 1
AND zj.notification_status = 3
AND zj.audit_opinion=2
AND zj.con_status = #{queryType}
) gh
ORDER BY gh.createTime DESC LIMIT #{offset}, #{limit}
</select>
</mapper>

View File

@ -158,8 +158,19 @@
"style": {
"navigationBarTitleText": "采购单审批"
}
}
],
},
{
"path": "pages/unqualifiedNotificationConfirm/unqualifiedNotificationConfirm",
"style": {
"navigationBarTitleText": "品质异常确认"
}
},{
"path": "pages/unqualifiedNotificationConfirm/unqualifiedNotificationConfirm-detail",
"style": {
"navigationBarTitleText": "详情"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "",

View File

@ -6,7 +6,13 @@ import CustomNavbar from "./components/CustomNavbar.vue";
import CategoryPanel from "./components/CategoryPanel.vue";
import footRight from "./components/footRight.vue";
import PageSkeleton from "./components/PageSkeleton.vue";
import {countReview, getHomeCategoryAPI, getUnreadMessage,countUnqualifiedNotification} from "@/services/home";
import {
countReview,
getHomeCategoryAPI,
getUnreadMessage,
countUnqualifiedNotification,
countUnqualifiedNotificationConfirm
} from "@/services/home";
//
const categoryList = ref([
{
@ -73,6 +79,13 @@ const categoryList = ref([
defaultImgUrl: "/static/images/assembleReport-default.png",
unReadCount: 0, //
},
{
path: "unqualifiedNotificationConfirm",
name: "品质异常确认",
auth: true,
imgUrl: "/static/images/unqualifiedNotification.png",
defaultImgUrl: "/static/images/unqualifiedNotification-default.png",
},
]);
const loginStore = useLoginStore();
const isLogin = computed(() => {
@ -106,7 +119,7 @@ const getHomeCategory = async () => {
e.auth = !!target;
});
}
// categoryList.value = categoryList.value.filter(item => item.auth == true);
categoryList.value = categoryList.value.filter(item => item.auth == true);
const unReadCount = await getUnreadMessage();
@ -114,7 +127,11 @@ const getHomeCategory = async () => {
var query ={
queryType:2,
}
var query1 ={
queryType:1,
}
const unqualifiedNotificationCount = await countUnqualifiedNotification(query);
const unqualifiedNotificationCountConfirm = await countUnqualifiedNotificationConfirm(query1);
//
const cgdsp = categoryList.value.find(
(e) => e.path === "cgdsp"
@ -125,6 +142,9 @@ const getHomeCategory = async () => {
const unqualifiedNotificationItem = categoryList.value.find(
(e) => e.path === "unqualifiedNotification"
);
const unqualifiedNotificationConfirm = categoryList.value.find(
(e) => e.path === "unqualifiedNotificationConfirm"
);
if (cgdsp){
cgdsp.unReadCount = count;
// cgdsp.auth=true
@ -136,7 +156,9 @@ const getHomeCategory = async () => {
if(unqualifiedNotificationItem){
unqualifiedNotificationItem.unReadCount = unqualifiedNotificationCount
}
if(unqualifiedNotificationConfirm){
unqualifiedNotificationConfirm.unReadCount = unqualifiedNotificationCountConfirm
}
if (loginStore.userInfo.userId) {
const obj = {

View File

@ -0,0 +1,374 @@
<script setup lang="ts">
import { onMounted, computed, ref } from 'vue'
import { onShow, onLoad} from '@dcloudio/uni-app'
import {getNotificationConfirmPageAPI, getNotificationPageAPI, postAddAPI} from '@/services/unqualifiedNotification'
import { useLoginStore } from '@/stores/modules/login'
import { formatDate } from '@/utils/index'
import { update } from 'XrFrame/kanata/lib/frontend'
const userStore = useLoginStore()
const userId = userStore.userInfo.userId
const statusText = computed(() => {
const text = props.orderState == '0' ? '确认' : '查看'
return text
})
const dictInfo = userStore?.dictInfo || []
const notificationOpinionDictData = dictInfo.filter(e => e.dictType == 'heli_unqualified_notification_opinion') || []
const inspectionTypeDictData = dictInfo.filter(e => e.dictType == 'heli_inspection_type') || []
//
const isFinish = ref(false)
//
const isTriggered = ref(false)
// porps
const props = defineProps<{
orderState: string
}>()
//
const isLoading = ref(false)
//
const queryParams: Required<any> = {
pageNo: 1,
pageSize: 5,
queryType: parseFloat(props.orderState) +1 ,
// creator: userId,
minCreateTime: '',
maxCreateTime: ''
}
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 getNotificationConfirmPageAPI(queryParams)
isLoading.value = false
data.list.forEach((e) => {
const obj = userStore.dictInfo.find((q) => q.value == e.property) || {}
e.property = obj?.label
e.createTime = formatDate(e.createTime, 'YYYY-MM-DD')
const obj2 = notificationOpinionDictData.find(q => q.value == e.auditOpinion)
e.auditOpinion = obj2?.label
const obj3 = inspectionTypeDictData.find(q => q.value == e.type)
e.type = obj3?.label
})
//
dataList.value.push(...data.list)
//
if (queryParams.pageNo < data.total) {
//
queryParams.pageNo++
} else {
//
isFinish.value = true
}
}
const updateData = async () => {
isLoading.value = false
isFinish.value = false
queryParams.pageNo = 1
dataList.value = []
await getListData()
}
onMounted(async () => {
const today = new Date() //
const timeVal = today.setMonth(today.getMonth()-3)//
if (props.orderState == '0') {
queryParams.minCreateTime = formatDate(timeVal)
delete queryParams.maxCreateTime
} else {
delete queryParams.minCreateTime
queryParams.maxCreateTime = formatDate(timeVal)
}
dataList.value = []
await getListData()
})
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.pageNo = 1
dataList.value = []
isFinish.value = false
//
await getListData()
//
isTriggered.value = false
}
onShow(async () => {
await getListData()
})
defineExpose({ updateData })
const showpicture= (pictureArray:[])=>{
let picture = JSON.stringify(pictureArray);
console.log(picture)
uni.navigateTo({
url: './components/showpicture?picture=' + encodeURIComponent(picture)
});
}
const handleDetail = (item) => {
var type = item.typeName == '终检'? 2:1
const url = `/pages/unqualifiedNotificationConfirm/unqualifiedNotificationConfirm-detail?id=${item.id}&type=${type}`
uni.navigateTo({ url })
}
</script>
<template>
<view class="cont">
<scroll-view enable-back-to-top scroll-y class="data-list" refresher-enabled :refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh" @scrolltolower="getListData">
<view class="item" @click="handleDetail(item)" v-for="item in dataList" :key="item.id" >
<view class="hd">
<view class="num">检验单据</view>
<view class="statusLabel">单号{{ item.code }}</view>
<view class="statusLabelzf" >
{{ statusText }}
</view>
</view>
<view class="md">
<view class="product-item">项目<text class="blue">{{ item.projectName}}</text>
</view>
<view class="product-item">通知日期<text class="">{{ item.createTime }}</text></view>
<view class="product-row" v-if="item.typeName == '过程检'">
<view class="row-item">
<view class="label">零件名称<text class="blue">{{ item.materialName }}</text></view>
</view>
<view class="row-item">
<view class="label">工序<text class="blue">{{ item.procedureName }}</text></view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">质检员<text class="blue">{{ item.creatorName }}</text></view>
</view>
<view class="row-item">
<view class="label">类型<text class="blue">{{ item.typeName }}</text></view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">检查数量<text class="blue">{{ item.amount }}</text></view>
</view>
<view class="row-item">
<view class="label">派工总数量<text class="blue">{{ item.totalAmount }}</text></view>
</view>
</view>
<view class="product-item">子项目<text class="blue">{{ item.projectSubCode || '' }} {{' ' +
item.projectSubName }}</text></view>
<!-- <view class="product-item">客户名称<text class="blue">{{ item.customerName }}</text></view> -->
<!-- <view v-if="item.fileUrlList && item.fileUrlList.length>0">
<text class="blue" @click="showpicture(item.fileUrlList)">查看图片</text>
</view>
<view v-if="!item.fileUrlList">
<text class="red">暂无图片</text>
</view> -->
<!-- <view class="product-item">零件名称<text class="blue">{{ item.materialName }}</text></view>
<view class="product-row">
<view class="row-item">
<view class="label">图号<text class="blue">{{ item.blueprintNo }}</text></view>
</view>
<view class="row-item">
<view class="label">材质<text class="blue">{{ item.compositionName }}</text></view>
</view>
</view>
<view class="product-item">责任工序<text class="blue">{{ item.procedureName }}</text></view>
<view class="product-row">
<view class="row-item">
<view class="label">异常数量<text class="blue">{{ item.amount }}</text></view>
</view>
<view class="row-item">
<view class="label">责任人<text class="blue">{{ item.ownerName }}</text></view>
</view>
</view>
<view class="product-item">
<view class="label">异常情况描述及原因分析</view>
<text class="blue">{{ item.remark }}</text>
</view> -->
<view class="product-row" v-if="item.auditorName">
<view class="row-item">
<view class="label">审核人<text class="high-color">{{ item.auditorName }}</text></view>
</view>
<view class="row-item">
<view class="label">审核意见<text class="auditOpinion">{{ item.auditOpinion }}</text></view>
</view>
</view>
</view>
<!-- <image v-if="item.notificationStatus == 3" src="/static/images/unqualifiedNotification-agree.png"-->
<!-- class="icon-status" mode="scaleToFit" />-->
</view>
<!-- 底部提示文字 -->
<view class="loading-text" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
{{ isFinish ? '没有更多数据~' : '正在加载...' }}
</view>
</scroll-view>
</view>
</template>
<style lang="scss">
//
.cont {
height: 100vh;
overflow: auto;
position: reactive;
}
.data-list {
.item {
position: relative;
padding: 20rpx 0;
margin: 20rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
.hd {
padding: 10rpx;
font-size: 32rpx;
display: flex;
.statusLabel {
font-size: 28rpx;
color: #737D88;
}
.statusLabelzf {
font-size: 24rpx;
position: absolute;
right: 30rpx;
top: 15rpx;
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;
}
}
.md {
position: relative;
padding: 10rpx;
min-height: 100rpx;
font-size: 28rpx;
border-top: 2rpx solid #F2F2F2;
.product-item {
margin: 20rpx 0;
display: flex;
color: #737D88;
.label {
width: 390rpx;
}
}
.product-row {
margin: 20rpx 0;
display: flex;
flex-direction: row;
justify-content: space-between;
color: #737D88;
.row-item {
flex: 1;
display: flex;
flex-direction: row;
.label {
margin-bottom: 10rpx;
.high-color {
color: #1D2129;
}
.auditOpinion {
color: #FF7D00;
}
}
.val {
color: #1D2129;
.high-color {
color: #FF7D00;
}
}
}
}
}
.statusText {
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;
}
.blue {
color: #409EFF;
}
.icon-status {
position: absolute;
right: 30rpx;
top: 60rpx;
width: 140rpx;
height: 100rpx;
transform: rotate(30deg);
}
&:last-child {
padding-bottom: 40rpx;
}
}
.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>

View File

@ -0,0 +1,415 @@
<script setup lang="ts">
import { toRaw, ref, onMounted } from 'vue'
import { formatDate } from '@/utils/index'
import { getApproveOrderAPI, getChildProductAPI ,getApproveOrderAPIWx} from '@/services/approveOrder'
import { getBomPageAPI, getProcedurePageAPI, getUserPageAPI, postAddAPI } from '@/services/unqualifiedNotification'
import { onLoad } from '@dcloudio/uni-app'
import { useLoginStore } from '@/stores/modules/login'
import mySelect from './mySelect.vue'
import htzImageUpload from '@/components/htz-image-upload/htz-image-upload.vue'
import { serviceDomain } from '@/services/constants'
//
const emit = defineEmits<{
(event : 'close') : void
}>()
const userStore = useLoginStore()
const dictData = userStore.dictInfo
const userId = userStore.userInfo.userId
const userName = userStore.userInfo.nickname
//
const detailInfo = ref({})
let isLoading = ref(false)
//
let typeDictData = []
const getTypeDictData = () => {
const arr = dictData.filter(e => e.dictType == 'heli_inspection_type') || []
arr.forEach(e => {
const obj = {
value: e.value,
text: e.label
}
typeDictData.push(obj)
})
}
//
const projectData = ref([])
const getProjectData = async () => {
const params = {
pageNo: 1,
pageSize: 999,
orderStatusList: '32',
isSnapshot: 0,
deliveryStatusList: '1,2' // 1|2|3
}
const data = await getApproveOrderAPIWx(params)
const arr = []
data.list.forEach(e => {
const obj = {
text: e.projectName,
value: e.id
}
arr.push(obj)
})
console.log(arr)
projectData.value = arr
}
const projectChildData = ref([])
const getProjectChildData = async (projectOrderId) => {
if (!projectOrderId) {
return
}
const params = {
projectOrderId,
}
const data = await getChildProductAPI(params)
const arr = []
data.forEach(e => {
const obj = {
text: e.name,
value: e.id
}
arr.push(obj)
})
projectChildData.value = arr
}
//
const bomData = ref([])
const getBomData = async (projectOrderId) => {
if (!valiFormData.value.projectSubId) {
return
}
const params = {
pageNo: 1,
pageSize: 99,
projectId: valiFormData.value.projectId,
projectSubId: valiFormData.value.projectSubId,
materialType: 2
}
const data = await getBomPageAPI(params)
const arr = []
data.list.forEach(e => {
const obj = {
text: e.materialName,
value: e.bomDetailId
}
arr.push(obj)
})
bomData.value = arr
}
//
const procedureData = ref([])
const getProcedurePage = async (projectOrderId) => {
const params = {
pageNo: 1,
pageSize: 99,
}
const data = await getProcedurePageAPI(params)
const arr = []
data.list.forEach(e => {
const obj = {
text: e.name,
value: e.id
}
arr.push(obj)
})
procedureData.value = arr
}
//
const ownerData = ref([])
let ownerDataDefault = []
const getOwnerDataData = async (projectOrderId) => {
const params = {
pageNo: 1,
pageSize: 99,
}
const data = await getUserPageAPI(params)
const arr = []
data.list.forEach(e => {
const obj = {
text: e.nickname,
value: e.id
}
arr.push(obj)
})
ownerData.value = arr
ownerDataDefault = arr
}
onMounted(async () => {
// isLoading.value = true
await getTypeDictData()
await getProjectData()
await getBomData()
// await getProcedurePage()
await getOwnerDataData()
// isLoading.value = false
})
//
const formRef = ref<UniHelper.UniFormsInstance>()
const valiFormData = ref({
type: '', //
projectId: '', // id
projectSubId: '', // id
// bomDetailId: '', //
// procedureId: '', //id
// amount: '',
// owner: '',
// remark: '',
status: 1, // ,12,(1)
notificationStatus: 2, // || 1|2|32
fileList: [],
active: 'SUBMIT'
})
//
const rules : UniHelper.UniFormsRules = {
type: {
rules: [{ required: true, errorMessage: '请选择质检类型' }],
},
projectId: {
rules: [{ required: true, errorMessage: '请选择项目名称' }],
},
projectSubId: {
rules: [{ required: true, errorMessage: '请选择子项目名称' }],
},
}
//
const handleChangeType = (val) => {
valiFormData.value.type = val
//
if (val == 1) {
valiFormData.value.owner = userId
} else {
valiFormData.value.owner = ''
}
}
//
const handleChangeProject = (val) => {
valiFormData.value.projectId = val
valiFormData.value.projectSubId = ''
projectChildData.value = []
valiFormData.value.bomDetailId = ''
bomData.value = []
getProjectChildData(val)
}
//
const handleChangeProjectChild = (val) => {
valiFormData.value.projectSubId = val
valiFormData.value.bomDetailId = ''
bomData.value = []
getBomData(val)
}
const resultId = ref();
//
const handleCancl = () => {
emit('close', false)
}
//
const handleSubmit = async () => {
if(!(imageDataType1.value != null &&imageDataType1.value.length>0)){
uni.showToast({ icon: 'none', title: '请上传图片~' })
return
}
await formRef.value?.validate?.()
// Blob URLs Blobs FormData
const params = {
...valiFormData.value
}
resultId.value = await postAddAPI(params)
valiFormData.value.type = ''
valiFormData.value.projectId = ''
valiFormData.value.projectSubId = ''
valiFormData.value.bomDetailId = ''
valiFormData.value.procedureId = ''
valiFormData.value.amount = ''
valiFormData.value.owner = ''
valiFormData.value.remark = ''
await imgUpload()
}
//
const selectOne = (val : string) => {
if (val) {
ownerData.value = ownerDataDefault.filter((e) => {
if (e.text.indexOf(val) != -1) {
return e
}
})
} else {
ownerData.value = ownerDataDefault
}
}
const imgDelete = (del, tempFilePaths) => {
}
//
const selectConfirm = (val : string) => {
}
const uploadImagFail = () => {
}
//
interface ImageDataItem {
url : string;
}
// thisDatas imageDataType1 ImageDataItem
const thisDatas = ref([]);
const imageDataType1 = ref([]);
const choocessImag = (tempFilePaths, e) => {
//console.log('ceshiChooseSuccessDataType1', tempFilePaths, e);
var thisDatas = []
tempFilePaths.forEach(item => {
thisDatas.push({
type: e,
url: item
})
})
imageDataType1.value.push(...thisDatas)
};
const imgUpload= async()=> {
const storage_token = uni.getStorageSync('storage_loginInfo')?.accessToken
const token = userStore.userInfo?.accessToken || storage_token
//console.log('imgUpload', tempFilePaths)
let uploadImgs = [];
imageDataType1.value.forEach(item => {
uploadImgs.push(new Promise((resolve, reject) => {
uni.showLoading({
title: '上传中'
});
//console.log(index, item)
uni.uploadFile({
url: serviceDomain+"/admin-api/heli/unqualified-notification/createWx",
filePath: item.url,
name: 'file',
header:{
id:resultId.value ,
Authorization: token,
 'Tenant-Id': 2,
},
success: (uploadFileRes) => {
uni.hideLoading();
emit('close', true)
},
fail: (err) => {
uni.hideLoading();
reject(err);
},
complete: () => {
uni.hideLoading();
}
});
}))
})
// Promise.all(uploadImgs) //
// .then((results) => {
// uni.hideLoading();
// })
// .catch((res, object) => {
// uni.hideLoading();
// });
};
</script>
<template>
<view class="data-detail">
<template v-if="!isLoading">
<!-- 基础表单校验 -->
<uni-forms ref="formRef" :rules="rules" :modelValue="valiFormData" :label-width="100">
<uni-forms-item label="质检类型" required name="type">
<uni-data-select v-model="valiFormData.type" require :localdata="typeDictData"
@change="handleChangeType"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="项目名称" required name="projectId">
<uni-data-select v-model="valiFormData.projectId" :localdata="projectData"
@change="handleChangeProject"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="子项目名称" required name="projectSubId">
<uni-data-select v-model="valiFormData.projectSubId" :localdata="projectChildData"
@change="handleChangeProjectChild"></uni-data-select>
</uni-forms-item>
<!-- <uni-forms-item label="零件名称" name="bomDetailId">
<uni-data-select v-model="valiFormData.bomDetailId" :localdata="bomData"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="责任工序" name="procedureId">
<uni-data-select v-model="valiFormData.procedureId" :localdata="procedureData"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="异常数量" name="amount">
<uni-easyinput type="number" v-model="valiFormData.amount" placeholder="请输入异常数量" />
</uni-forms-item>
<uni-forms-item label="责任人" name="owner">
<template v-if="valiFormData.type == 1">
<uni-easyinput type="text" disabled :value="userName" />
</template>
<template v-else>
<mySelect :list="ownerData" value-key="value" name-key="text" max-height="180"
placeholder="请输入责任人" @input="selectOne" v-model="valiFormData.owner"
@confirm="selectConfirm" />
</template>
</uni-forms-item>
<uni-forms-item label="情况描述" name="remark">
<uni-easyinput type="textarea" v-model="valiFormData.remark" placeholder="请输入情况描述" />
</uni-forms-item> -->
<uni-forms-item label="图片上传" require name="photo">
<htz-image-upload v-model="imageDataType1" mediaType="image" :sourceType="['album','camera']"
:max="19" :compress="true" :quality="80" :formData="valiFormData" :remove="true" :dataType="1"
@imgDelete="imgDelete" @uploadFail="uploadImagFail"
@chooseSuccess="choocessImag"></htz-image-upload>
</uni-forms-item>
</uni-forms>
<view class="action">
<button class="cancle" @click="handleCancl()">取消</button>
<button class="submit" @click="handleSubmit()">提交</button>
</view>
</template>
<view class="loading-text" v-else>加载中..</view>
</view>
</template>
<style lang="scss" scoped>
//
.data-detail {
height: 80vh;
z-index: 9999;
padding: 20rpx 40rpx;
margin: 20rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
padding-bottom: 200rpx;
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
.uni-section {
display: flex !important;
align-items: center !important;
}
.action {
display: flex;
justify-content: space-between;
align-items: center;
.cancle {
color: #356899;
background-color: #F9FCFF;
padding: 0rpx 100rpx;
margin-right: 20rpx;
}
.submit {
// background-color: #F9FCFF;
padding: 0rpx 100rpx;
color: #fff;
background: linear-gradient(170deg, #2DACE6 -128%, #356899 141%);
}
}
}
</style>

View File

@ -0,0 +1,250 @@
<template>
<view>
<!-- 兼容vue2-->
<view class="lin-fixed" v-show="showComboxSelect" @click="gclick"></view>
<view class="lin-combox">
<uni-easyinput ref="uni-easyinput" :placeholder="placeholder" type="text" @input="oninput" />
<view class="lin-combox-select" v-show="showComboxSelect">
<view class="lin-popper__arrow"></view>
<scroll-view scroll-y="true" :style="'max-height:' + maxHeight + 'px;'">
<view v-if="loading" class="fedback-popper_loading">{{ loadingText }}</view>
<template v-else>
<view v-if="!list.length" class="fedback-popper_nodata">暂无数据</view>
<view v-else class="items" v-for="item, key in list" :key="key" :id="key" @click="comboxCheckHandel(item)">
{{ item[nameKey] }}
</view>
</template>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
export default {
emits: ['update:modelValue', 'input', 'confirm'],
props: {
loading: {
type: Boolean,
default: false
},
maxHeight: {
type: String || Number,
default: 125
},
valueKey: {
type: String,
default: 'value'
},
nameKey: {
type: String,
default: 'name'
},
placeholder: {
type: String,
default: '请输入'
},
loadingText: {
type: String,
default: '加载中'
},
modelValue: [Number, String],
value: [Number, String],
list: {
type: Array,
default: () => []
}
},
data() {
return {
showComboxSelect: false,
checkValue: '',
inputVal: ''
}
},
created() {
},
mounted() {
if (!this.$refs['uni-easyinput']) {
console.error('请先导入uni-easyinput插件')
return
}
this.watchInitialValue()
},
watch: {
checkValue(val) { },
list: {
handler(val) {
// console.log(val, 'watch')
}
}
},
methods: {
gclick() {
this.showComboxSelect = false
this.reset()
},
/*
* 判断如果数据源有数据直接获取没有数据就进行监听
*/
watchInitialValue() {
if (this.list.length) {
this.getInitText()
return
}
const unwatchList = this.$watch('list', (val) => {
this.getInitText()
unwatchList()
})
},
getInitText() {
this.checkValue = this.modelValue || this.value
this.inputVal = this.checkValue
if (!this.list.length) return
if (this.checkValue === '' || this.checkValue === undefined || this.checkValue === null) return
if (this.showComboxSelect) return
const _item = this.list.find((item) => {
return item[this.valueKey] === this.checkValue
})
this.$refs['uni-easyinput'].val = _item[this.nameKey]
},
/**
* 重置
*/
reset() {
// #ifdef VUE3
this.$emit('update:modelValue', '')
// #endif
// #ifdef VUE2
this.$emit('input', '')
// #endif
this.$nextTick(() => {
this.$refs['uni-easyinput'].val = ''
})
},
/**
* 选中事件
*/
comboxCheckHandel(item) {
const text = item[this.nameKey]
const value = item[this.valueKey]
this.checkValue = ''
this.checkValue = value
this.showComboxSelect = false
// #ifdef VUE3
this.$emit('update:modelValue', value)
// #endif
// #ifdef VUE2
this.$emit('input', value)
// #endif
this.$nextTick(() => {
this.$refs['uni-easyinput'].val = text
})
this.$emit('confirm', value)
},
/**
* 输入事件
*/
oninput(val) {
this.$emit('update:modelValue', val);
this.$emit('input', val)
if (!val) {
this.showComboxSelect = false
return
}
this.showComboxSelect = true
}
}
}
</script>
<style lang="scss" scoped>
.lin-fixed {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
}
.lin-combox {
position: relative;
.lin-combox-select {
position: absolute;
top: 45px;
left: 0;
right: 0;
background-color: #fff;
z-index: 2;
border-radius: 3px;
padding: 3px 0;
z-index: 8;
background-color: #fff;
border: 1px solid #ebeef5;
border-radius: 6px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
.fedback-popper_nodata {
font-size: 13px;
padding: 5px;
color: #5d5959;
text-align: center;
}
.lin-popper__arrow {
position: absolute;
top: -13px;
left: 32px;
z-index: 3;
content: '';
width: 0;
height: 0;
display: block;
border-color: transparent;
border-style: solid;
border-width: 6px;
border-bottom-color: #ebeef5;
&::before {
content: '';
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 6px;
top: 1px;
margin-left: -6px;
border-top-width: 0;
border-bottom-color: #fff;
}
}
.items {
height: 35px;
line-height: 35px;
padding: 0 10px;
font-size: 15px;
}
.fedback-popper_loading {
text-align: center;
font-size: 13px;
padding: 5px;
color: #5d5959;
}
}
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<view>
<!-- <image v-for="(item, index) in src" :key="index" :src="item" @click="preview(item)" mode="aspectFill" @error="imageError"></image> -->
<htz-image-upload v-model="src" :max="9" :remove="false" :add="false"></htz-image-upload>
</view>
</template>
<script setup>
import { reactive, ref, toRefs,nextTick,onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { onLoad, onShow } from '@dcloudio/uni-app'
import htzImageUpload from '@/components/htz-image-upload/htz-image-upload.vue'
const title = ref('图片预览');
const src = ref([]);
const route = useRoute();
const picture = ref('');
const previewImage = ref(null);
const imageError = (event) => {
console.error('Image load error:', event.detail.errMsg);
};
const preview = (url) => {
// #ifdef MP-WEIXIN
this.$nextTick(()=>{
previewImage.value.open(url);
})
// #endif
// #ifndef MP-WEIXIN
previewImage.value.open(url);
// #endif
};
const onLongpress = e =>{
console.log('当前长按的图片是' + e);
uni.showActionSheet({
itemList: ['转发给朋友', '保存到手机'],
success: function (res) {
console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
},
fail: function (res) {
console.log(res.errMsg);
}
});
}
onLoad( (options) => {
picture.value = options.picture;
console.log(picture.value)
if (picture.value) {
try {
var fileUrlList = decodeURIComponent(picture.value);
src.value = JSON.parse(fileUrlList);
console.log(src.value)
} catch (error) {
console.error('Error parsing picture data:', error);
}
}
})
// const previewImage = (index) => {
// const urls = src.value.map(item => item.url);
// uni.previewImage({
// current: index,
// urls: urls,
// longPressActions: {
// itemList: [''],
// success: (data) => {
// saveImage(urls[data.index]);
// },
// fail: (err) => {
// console.error(err);
// }
// }
// });
// };
const saveImage = (url) => {
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '图片保存成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '图片保存失败',
icon: 'none'
});
}
});
}
}
});
};
</script>
<style>
/* ... other styles ... */
.thumbnail-container {
display: flex;
flex-wrap: wrap;
/* Other styles */
}
.thumbnail-wrapper {
margin: 10px;
/* Other styles */
}
.clickable-image {
cursor: pointer;
}
</style>

View File

@ -0,0 +1,690 @@
<script setup lang="ts">
import { toRaw, ref, computed } from 'vue'
import { formatDate } from '@/utils/index'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { useLoginStore } from '@/stores/modules/login'
import { getNotificationDetailAPI, operateWx } from '@/services/unqualifiedNotification'
import { serviceDomain } from '@/services/constants'
const popup = ref<UniHelper.UniPopupInstance>()
const userStore = useLoginStore()
const dictInfo = userStore?.dictInfo || []
const unitDictData = dictInfo.filter(e => e.dictType == 'heli_material_unit') || []
const userId = userStore.userInfo.userId
const isShowStart = ref(false)
const isShowEnd = ref(false)
// const isShowStart = computed(() => {
// let flag = true
// if (historyList.value.length) {
// const obj = historyList.value[0]
// if (!obj?.endTime) {
// flag = false
// }
// }
// // //
// // if (detailInfo.value.amount == detailInfo.value.totalReportAmount) {
// // flag = false
// // }
// return flag
// })
// const isShowEnd = computed(() => {
// let flag = true
// if (historyList.value.length) {
// const obj = historyList.value[0]
// if (obj?.endTime) {
// flag = false
// }
// } else {
// flag = false
// }
// return flag
// })
const productionTitle = ref('开始生产')
const amount = ref('')
const workTime = ref('')
//
const detailInfo = ref({})
let isLoading = ref(false)
const historyList = ref([])
const formObj = ref({})
//
const getData = async () => {
//
isLoading.value = true
const params = {
pageNo: 1,
integerpageSize: 5,
bgUser: userId,
zjMxId: detailInfo.value.id,
}
const data = await getTaskRepotPageAPI(params)
data.list.forEach((e) => {
e.startTimeStr = e.startTime && formatDate(e.startTime, 'YYYY-MM-DD HH:mm')
e.endTimeStr = e.endTime && formatDate(e.endTime, 'YYYY-MM-DD HH:mm')
e.bgTime = e.bgTime && formatDate(e.bgTime, 'YYYY-MM-DD HH:mm')
e.entTime = e.entTime && formatDate(e.entTime, 'YYYY-MM-DD HH:mm')
})
if (data.list[0]) {
formObj.value = data.list[0]
const time = formObj.value.endTime - formObj.value.startTime //
const leave1 = time % (24 * 3600 * 1000) //
workTime.value = Math.floor(leave1 / (3600 * 1000))
}
historyList.value = data.list
isShowEnd.value = true;
isShowStart.value = true
if (historyList.value.length) {
const obj = historyList.value[0]
if (obj.amount != null && obj.amount >= 0) {
isShowStart.value = true
} else {
isShowStart.value = false
}
}
if (historyList.value.length) {
const obj = historyList.value[0]
if (obj.amount != null && obj.amount >= 0) {
isShowEnd.value = false
} else {
isShowEnd.value = true
detailId.value = obj.id
}
} else {
isShowEnd.value = false
}
isLoading.value = false
isLoading.value = false
}
//
const getDetailData = async (id, type) => {
//
// isLoading.value = true
//
const queryParams = {
id: id,
type: type
}
detailInfo.value = await getNotificationDetailAPI(queryParams)
}
const idValue = ref()
onLoad(async (options : any) => {
idValue.value = options.id
typeName.value = options.type == 2 ? '终检' : '过程检'
await getDetailData(options.id, typeName.value)
})
//
const handleComplate = async () => {
try {
isLoading.value = true;
const params = {
zjMxId: detailInfo.value?.id,
bgUser: userId,
type: 0,
}
const data = await postOperateAPIEnd(params)
} catch (error) {
uni.showToast({
icon: 'none',
duration: 3000,
title: error.data.msg,
})
} finally {
isLoading.value = false;
// const url = `/pages/pgMaster/pgMaster-detail?id=${detailInfo.value.id}`
// uni.redirectTo({
// url,
// })
await initPage();
const pages = getCurrentPages(); //
const currentPage = pages[pages.length - 1]; //
const url = `/${currentPage.route}?${Object.entries(currentPage.options).map(([key, val]) => `${key}=${val}`).join('&')}`;
uni.reLaunch({ url }); //
}
}
const range = [
{ value: 1, text: "返修" },
{ value: 2, text: "让步接收" },
{ value: 3, text: "报废" },
]
//
const handleOk = async () => {
if (detailInfo.value.auditOpinion) {
await submitForm(detailInfo.value.auditOpinion);
} else {
uni.showToast({
icon: 'none',
duration: 3000,
title: '请选择审核意见后提交',
})
return;
}
}
const submitForm = async (active) => {
try {
const params = {
id: detailInfo.value?.id,
type: typeName.value,
auditOpinion: active,
auditor: userId,
projectId: 0,
projectSubId: 0,
status: 1,
notificationStatus: 3
}
await operateWx(params);
} catch (error) {
uni.showToast({
icon: 'none',
duration: 3000,
title: error.data.msg,
})
} finally {
isLoading.value = false;
// const url = `/pages/unqualifiedNotification/unqualifiedNotification`
// uni.redirectTo({
// url,
// })
const pages = getCurrentPages(); //
await initPage();
const currentPage = pages[pages.length - 1]; //
const url = `/${currentPage.route}?${Object.entries(currentPage.options).map(([key, val]) => `${key}=${val}`).join('&')}`;
uni.reLaunch({ url }); //
}
}
const typeName = ref('')
const initPage = async () => {
await getDetailData(idValue.value, typeName.value)
}
const audit =async () => {
// popup.value.open()
await submitForm(detailInfo.value.auditOpinion);
}
const cancel = () => {
uni.navigateBack({
delta: 1 // 1
});
}
const getSuger = (val) => {
if (val == 1) {
return '返修'
} else if (val == 2) {
return '让步接收'
} else if (val == 3) {
return '报废'
}
}
const detailId = ref()
</script>
<template>
<view class="data-detail">
<template v-if="!isLoading">
<view class="module">
<view class="module-info">
<view class="product-item">检验单据{{detailInfo.code}}</view>
<image src="/static/images/productionReport-page.png" class="product-img" mode="scaleToFill">
</image>
<view :class="[detailInfo.notificationStatus == 3 ? 'had' : 'unhad', 'product-status']">{{
detailInfo.notificationStatus == 2 ? '未审核' : '已审核' }}</view>
<view class="product-item">项目{{detailInfo.projectName}}</view>
<view class="product-item">子项目{{ detailInfo.projectSubCode || '' }}
{{' ' + detailInfo.projectSubName }}
</view>
<view class="product-item">通知日期{{formatDate(detailInfo.createTime, 'YYYY-MM-DD HH:mm')}}</view>
<view class="product-item" v-if="detailInfo.notificationStatus === 3">
审核日期{{formatDate(detailInfo.auditTime, 'YYYY-MM-DD HH:mm')}}</view>
<view class="product-item" v-if="detailInfo.notificationStatus === 3">
审核意见{{getSuger(detailInfo.auditOpinion)}}</view>
<view class="product-row" v-if="detailInfo.typeName == '过程检'">
<view class="row-item">
<view class="label">零件名称<text class="blue">{{ detailInfo.materialName }}</text></view>
</view>
<view class="row-item">
<view class="label">工序<text class="blue">{{ detailInfo.procedureName }}</text></view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">质检员<text class="blue">{{ detailInfo.creatorName }}</text></view>
</view>
<view class="row-item">
<view class="label">类型<text class="blue">{{ detailInfo.typeName }}</text></view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">检查数量<text class="blue">{{ detailInfo.amount }}</text></view>
</view>
<view class="row-item">
<view class="label">派工总数量<text class="blue">{{ detailInfo.totalAmount }}</text></view>
</view>
</view>
<!-- <view class="product-item">预计生产日期{{ detailInfo.startTime }} {{ detailInfo.entTime }}</view> -->
<!-- <view class="finish" v-if="isShowStart && historyList.length &&detailInfo.pgType != 1"
@click="handleComplate">
<image class="complate-img" src="/static/images/productionReport-detail-complate.png"
mode="scaleToFill" />
生产完成
</view> -->
</view>
</view>
<view class="module-list">
<view class="module-title">异常明细</view>
<view class="history-list">
<view class="item">
<view class="product-row">
<view class="row-item">
<view class="label">是否复检</view>
<view class="val high-color">{{ detailInfo.isRepre == 1 ?'否':'是' }}</view>
</view>
<view class="row-item">
<view class="label">是否合格</view>
<view class="val high-color">{{ detailInfo.isQua == 0?'合格':'不合格' }}</view>
</view>
</view>
<view v-if="detailInfo.remark" class="product-item">异常描述{{ detailInfo.remark }}</view>
<view v-if="!detailInfo.fileUrlList">
<text class="red">暂无图片</text>
</view>
<view v-else>
<htz-image-upload v-model="detailInfo.fileUrlList" :max="9" :remove="false"
:add="false"></htz-image-upload>
</view>
<viw></viw>
</view>
</view>
</view>
<view class="action" >
<!-- <view class="action-item info" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(3)">报废</view>
<view class="action-item start" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(1)">返修</view>
<view class="action-item stop" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(2)">让步接收</view> -->
<view class="action-item info" @click="cancel()">取消</view>
<view class="action-item start" v-if="detailInfo.conStatus !== 2" @click="audit()">确认</view>
<!-- <view class="action-item stop" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(2)">让步接收</view> -->
</view>
<uni-popup class="popup" ref="popup" :mask-click="false" type="bottom" background-color="#fff">
<view class="title">
<view class="text">审核信息</view>
<!-- <view class="close" @click="handleClose">X</view> -->
</view>
<view class="formHeight">
<uni-forms ref="formRef" :label-width="100">
<uni-forms-item class="auditSelect" label="审核意见" required name="type">
<uni-data-select style="width: 60%;" v-model="detailInfo.auditOpinion" :localdata="range"></uni-data-select>
</uni-forms-item>
</uni-forms>
</view>
<view class="ok" @click="handleOk">确定</view>
</uni-popup>
</template>
</view>
</template>
<style lang="scss">
.auditSelect{
margin-top: 10%;
margin-left: 10%;
}
.formHeight{
height: 600rpx;
}
//
.data-detail {
border-radius: 10rpx;
padding-bottom: 200rpx;
.statusLabelzf {
font-size: 24rpx;
position: absolute;
right: 30rpx;
top: 15rpx;
border-radius: 10rpx;
font-size: 24rpx;
padding: 10rpx 30rpx;
border-radius: 10rpx;
font-size: 24rpx;
background: linear-gradient(149deg, #ffff00 4%, #cfcf00 98%);
color: #fff;
}
.module {
background: linear-gradient(178deg, #356899 7%, #356899 57%, #F4F6F9 94%);
padding: 20rpx;
.module-info {
padding: 20rpx 20rpx 80rpx;
border-radius: 10rpx;
min-height: 100rpx;
font-size: 28rpx;
border-bottom: 2rpx solid #F2F2F2;
background: linear-gradient(215deg, #C7D3E5 8%, rgba(222, 228, 236, 0) 13%), linear-gradient(162deg, #FFFFFF 25%, #E4EFFD 106%);
position: relative;
border-top-right-radius: 100rpx;
.product-img {
position: absolute;
right: 0rpx;
top: 0;
width: 100rpx;
height: 100rpx;
}
.product-status {
width: 140rpx;
border-radius: 10rpx;
text-align: center;
padding: 8rpx 12rpx;
&.had {
background: #E8FFEA;
color: #00B42A;
}
&.unhad {
background: #FFF7E8;
color: #FF7D00;
}
}
.product-item {
margin: 20rpx 0;
display: flex;
align-items: center;
color: #737D88
}
.product-row {
margin: 20rpx 0;
display: flex;
flex-direction: row;
justify-content: space-between;
color: #737D88;
.row-item {
flex: 1;
.label {
margin-bottom: 10rpx;
}
.val {
color: #1D2129;
&.high-color {
color: #00B42A
}
}
}
}
.finish {
position: absolute;
right: 40rpx;
bottom: 30rpx;
background: linear-gradient(142deg, #FEB34A 14%, #FE9B12 83%);
color: #fff;
width: 200rpx;
text-align: center;
padding: 10rpx;
border-radius: 31rpx;
display: flex;
align-items: center;
justify-content: center;
.complate-img {
width: 30rpx;
height: 30rpx;
margin-right: 10rpx;
}
}
}
}
.module-list {
padding: 20rpx 20rpx;
// box-shadow: 0px 0px 8px 0px rgba(161, 161, 177, 0.12);
.module-title {
color: #0D0D26;
font-size: 36rpx;
margin: 20rpx 0;
font-weight: 500;
}
.history-list {
display: flex;
flex-direction: column;
align-items: center;
min-height: 200rpx;
justify-content: center;
padding: 0rpx 10rpx;
.item {
margin: 10rpx 0;
background: #EAEEF4;
font-size: 28rpx;
padding: 20rpx;
width: 100%;
border-radius: 10rpx;
color: #737D88;
position: relative;
.product-item {
margin: 10rpx 0;
.hight-color {
color: #00B42A;
}
}
.product-row {
margin: 20rpx 0;
display: flex;
flex-direction: row;
justify-content: space-between;
color: #737D88;
.row-item {
flex: 1;
display: flex;
flex-direction: row;
.label {
margin-bottom: 10rpx;
&.high-color {
color: #00B42A
}
}
.val {
color: #1D2129;
&.high-color {
color: #00B42A
}
}
}
}
.tip-index {
position: absolute;
top: 0rpx;
right: 0rpx;
.icon-status {
width: 100rpx;
height: 72rpx;
z-index: 1;
}
.text {
color: #fff;
position: absolute;
top: 4rpx;
right: 30rpx;
z-index: 2;
}
}
}
.no-data {
font-size: 28rpx;
color: #444;
}
}
.table-cont {
font-size: 24rpx;
}
.button {
color: #356899;
}
}
.action {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0rpx;
border-radius: 18rpx;
padding: 30rpx 30rpx;
background: #FFFFFF;
margin: 0 auto;
width: 100vw;
box-shadow: 0px -4px 10px 0px rgba(121, 153, 183, 0.2);
.action-item {
width: 272rpx;
height: 86rpx;
display: flex;
justify-content: center;
align-items: center;
margin: 0 20rpx;
font-size: 40rpx;
color: #fff;
width: 272rpx;
height: 86rpx;
border-radius: 24rpx;
&.info {
background: linear-gradient(157deg, #A9A9A9 -3%, #A9A9A9 90%);
}
&.start {
background: linear-gradient(157deg, #2EACE6 -3%, #356899 90%);
}
&.stop {
background: linear-gradient(167deg, #FEA97B -2%, #F75E40 87%);
}
&.danger {
background: linear-gradient(167deg, #C00000 -2%, #E80000 87%);
}
&.finish {
background: linear-gradient(142deg, #FEB34A 14%, #FE9B12 83%);
}
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
.popup {
.title {
line-height: 1;
padding: 40rpx;
font-size: 32rpx;
font-weight: normal;
border-bottom: 1rpx solid #ddd;
color: #444;
.close {
position: absolute;
right: 24rpx;
top: 40rpx;
height: 60rpx;
width: 60rpx;
text-align: center;
}
}
.cont {
display: flex;
flex-direction: column;
align-items: center;
margin: 40rpx;
height: 50vh;
.item {
display: flex;
align-items: center;
margin: 20rpx 0;
color: #737D88;
width: 94%;
.label {
font-size: 32rpx;
width: 260rpx;
.star {
color: red
}
}
.val {
flex: 1;
font-size: 32rpx;
}
.unit {
width: 100rpx;
margin-left: 4rpx;
text-align: center;
}
}
}
.ok {
font-size: 32rpx;
margin: 20rpx auto 80rpx;
text-align: center;
width: 200rpx;
border-radius: 10rpx;
padding: 8rpx 0;
background-color: #3C8AF7;
color: #fff;
}
}
}
</style>

View File

@ -0,0 +1,690 @@
<script setup lang="ts">
import { toRaw, ref, computed } from 'vue'
import { formatDate } from '@/utils/index'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { useLoginStore } from '@/stores/modules/login'
import { getNotificationDetailAPI, operateWx } from '@/services/unqualifiedNotification'
import { serviceDomain } from '@/services/constants'
const popup = ref<UniHelper.UniPopupInstance>()
const userStore = useLoginStore()
const dictInfo = userStore?.dictInfo || []
const unitDictData = dictInfo.filter(e => e.dictType == 'heli_material_unit') || []
const userId = userStore.userInfo.userId
const isShowStart = ref(false)
const isShowEnd = ref(false)
// const isShowStart = computed(() => {
// let flag = true
// if (historyList.value.length) {
// const obj = historyList.value[0]
// if (!obj?.endTime) {
// flag = false
// }
// }
// // //
// // if (detailInfo.value.amount == detailInfo.value.totalReportAmount) {
// // flag = false
// // }
// return flag
// })
// const isShowEnd = computed(() => {
// let flag = true
// if (historyList.value.length) {
// const obj = historyList.value[0]
// if (obj?.endTime) {
// flag = false
// }
// } else {
// flag = false
// }
// return flag
// })
const productionTitle = ref('开始生产')
const amount = ref('')
const workTime = ref('')
//
const detailInfo = ref({})
let isLoading = ref(false)
const historyList = ref([])
const formObj = ref({})
//
const getData = async () => {
//
isLoading.value = true
const params = {
pageNo: 1,
integerpageSize: 5,
bgUser: userId,
zjMxId: detailInfo.value.id,
}
const data = await getTaskRepotPageAPI(params)
data.list.forEach((e) => {
e.startTimeStr = e.startTime && formatDate(e.startTime, 'YYYY-MM-DD HH:mm')
e.endTimeStr = e.endTime && formatDate(e.endTime, 'YYYY-MM-DD HH:mm')
e.bgTime = e.bgTime && formatDate(e.bgTime, 'YYYY-MM-DD HH:mm')
e.entTime = e.entTime && formatDate(e.entTime, 'YYYY-MM-DD HH:mm')
})
if (data.list[0]) {
formObj.value = data.list[0]
const time = formObj.value.endTime - formObj.value.startTime //
const leave1 = time % (24 * 3600 * 1000) //
workTime.value = Math.floor(leave1 / (3600 * 1000))
}
historyList.value = data.list
isShowEnd.value = true;
isShowStart.value = true
if (historyList.value.length) {
const obj = historyList.value[0]
if (obj.amount != null && obj.amount >= 0) {
isShowStart.value = true
} else {
isShowStart.value = false
}
}
if (historyList.value.length) {
const obj = historyList.value[0]
if (obj.amount != null && obj.amount >= 0) {
isShowEnd.value = false
} else {
isShowEnd.value = true
detailId.value = obj.id
}
} else {
isShowEnd.value = false
}
isLoading.value = false
isLoading.value = false
}
//
const getDetailData = async (id, type) => {
//
// isLoading.value = true
//
const queryParams = {
id: id,
type: type
}
detailInfo.value = await getNotificationDetailAPI(queryParams)
}
const idValue = ref()
onLoad(async (options : any) => {
idValue.value = options.id
typeName.value = options.type == 2 ? '终检' : '过程检'
await getDetailData(options.id, typeName.value)
})
//
const handleComplate = async () => {
try {
isLoading.value = true;
const params = {
zjMxId: detailInfo.value?.id,
bgUser: userId,
type: 0,
}
const data = await postOperateAPIEnd(params)
} catch (error) {
uni.showToast({
icon: 'none',
duration: 3000,
title: error.data.msg,
})
} finally {
isLoading.value = false;
// const url = `/pages/pgMaster/pgMaster-detail?id=${detailInfo.value.id}`
// uni.redirectTo({
// url,
// })
await initPage();
const pages = getCurrentPages(); //
const currentPage = pages[pages.length - 1]; //
const url = `/${currentPage.route}?${Object.entries(currentPage.options).map(([key, val]) => `${key}=${val}`).join('&')}`;
uni.reLaunch({ url }); //
}
}
const range = [
{ value: 1, text: "返修" },
{ value: 2, text: "让步接收" },
{ value: 3, text: "报废" },
]
//
const handleOk = async () => {
if (detailInfo.value.auditOpinion) {
await submitForm(detailInfo.value.auditOpinion);
} else {
uni.showToast({
icon: 'none',
duration: 3000,
title: '请选择审核意见后提交',
})
return;
}
}
const submitForm = async () => {
try {
const params = {
id: detailInfo.value?.id,
type: typeName.value,
auditOpinion: undefined,
auditor: userId,
projectId: 0,
projectSubId: 0,
status: 1,
notificationStatus: 3
}
await operateWx(params);
} catch (error) {
uni.showToast({
icon: 'none',
duration: 3000,
title: error.data.msg,
})
} finally {
isLoading.value = false;
// const url = `/pages/unqualifiedNotificationConfirm/dataltem`
// uni.redirectTo({
// url,
// })
const pages = getCurrentPages(); //
await initPage();
const currentPage = pages[pages.length - 1]; //
const url = `/${currentPage.route}?${Object.entries(currentPage.options).map(([key, val]) => `${key}=${val}`).join('&')}`;
uni.reLaunch({ url }); //
}
}
const typeName = ref('')
const initPage = async () => {
await getDetailData(idValue.value, typeName.value)
}
const audit =async () => {
// popup.value.open()
await submitForm();
}
const cancel = () => {
uni.navigateBack({
delta: 1 // 1
});
}
const getSuger = (val) => {
if (val == 1) {
return '返修'
} else if (val == 2) {
return '让步接收'
} else if (val == 3) {
return '报废'
}
}
const detailId = ref()
</script>
<template>
<view class="data-detail">
<template v-if="!isLoading">
<view class="module">
<view class="module-info">
<view class="product-item">检验单据{{detailInfo.code}}</view>
<image src="/static/images/productionReport-page.png" class="product-img" mode="scaleToFill">
</image>
<view :class="[detailInfo.notificationStatus == 3 ? 'had' : 'unhad', 'product-status']">{{
detailInfo.notificationStatus == 2 ? '未审核' : '已审核' }}</view>
<view class="product-item">项目{{detailInfo.projectName}}</view>
<view class="product-item">子项目{{ detailInfo.projectSubCode || '' }}
{{' ' + detailInfo.projectSubName }}
</view>
<view class="product-item">通知日期{{formatDate(detailInfo.createTime, 'YYYY-MM-DD HH:mm')}}</view>
<view class="product-item" v-if="detailInfo.notificationStatus === 3">
审核日期{{formatDate(detailInfo.auditTime, 'YYYY-MM-DD HH:mm')}}</view>
<view class="product-item" v-if="detailInfo.notificationStatus === 3">
审核意见{{getSuger(detailInfo.auditOpinion)}}</view>
<view class="product-row" v-if="detailInfo.typeName == '过程检'">
<view class="row-item">
<view class="label">零件名称<text class="blue">{{ detailInfo.materialName }}</text></view>
</view>
<view class="row-item">
<view class="label">工序<text class="blue">{{ detailInfo.procedureName }}</text></view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">质检员<text class="blue">{{ detailInfo.creatorName }}</text></view>
</view>
<view class="row-item">
<view class="label">类型<text class="blue">{{ detailInfo.typeName }}</text></view>
</view>
</view>
<view class="product-row">
<view class="row-item">
<view class="label">检查数量<text class="blue">{{ detailInfo.amount }}</text></view>
</view>
<view class="row-item">
<view class="label">派工总数量<text class="blue">{{ detailInfo.totalAmount }}</text></view>
</view>
</view>
<!-- <view class="product-item">预计生产日期{{ detailInfo.startTime }} {{ detailInfo.entTime }}</view> -->
<!-- <view class="finish" v-if="isShowStart && historyList.length &&detailInfo.pgType != 1"
@click="handleComplate">
<image class="complate-img" src="/static/images/productionReport-detail-complate.png"
mode="scaleToFill" />
生产完成
</view> -->
</view>
</view>
<view class="module-list">
<view class="module-title">异常明细</view>
<view class="history-list">
<view class="item">
<view class="product-row">
<view class="row-item">
<view class="label">是否复检</view>
<view class="val high-color">{{ detailInfo.isRepre == 1 ?'否':'是' }}</view>
</view>
<view class="row-item">
<view class="label">是否合格</view>
<view class="val high-color">{{ detailInfo.isQua == 0?'合格':'不合格' }}</view>
</view>
</view>
<view v-if="detailInfo.remark" class="product-item">异常描述{{ detailInfo.remark }}</view>
<view v-if="!detailInfo.fileUrlList">
<text class="red">暂无图片</text>
</view>
<view v-else>
<htz-image-upload v-model="detailInfo.fileUrlList" :max="9" :remove="false"
:add="false"></htz-image-upload>
</view>
<viw></viw>
</view>
</view>
</view>
<view class="action" >
<!-- <view class="action-item info" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(3)">报废</view>
<view class="action-item start" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(1)">返修</view>
<view class="action-item stop" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(2)">让步接收</view> -->
<view class="action-item info" @click="cancel()">取消</view>
<view class="action-item start" v-if="detailInfo.conStatus !== 2" @click="audit()">确认</view>
<!-- <view class="action-item stop" v-if="detailInfo.notificationStatus !== 3" @click="submitForm(2)">让步接收</view> -->
</view>
<uni-popup class="popup" ref="popup" :mask-click="false" type="bottom" background-color="#fff">
<view class="title">
<view class="text">审核信息</view>
<!-- <view class="close" @click="handleClose">X</view> -->
</view>
<view class="formHeight">
<uni-forms ref="formRef" :label-width="100">
<uni-forms-item class="auditSelect" label="审核意见" required name="type">
<uni-data-select style="width: 60%;" v-model="detailInfo.auditOpinion" :localdata="range"></uni-data-select>
</uni-forms-item>
</uni-forms>
</view>
<view class="ok" @click="handleOk">确定</view>
</uni-popup>
</template>
</view>
</template>
<style lang="scss">
.auditSelect{
margin-top: 10%;
margin-left: 10%;
}
.formHeight{
height: 600rpx;
}
//
.data-detail {
border-radius: 10rpx;
padding-bottom: 200rpx;
.statusLabelzf {
font-size: 24rpx;
position: absolute;
right: 30rpx;
top: 15rpx;
border-radius: 10rpx;
font-size: 24rpx;
padding: 10rpx 30rpx;
border-radius: 10rpx;
font-size: 24rpx;
background: linear-gradient(149deg, #ffff00 4%, #cfcf00 98%);
color: #fff;
}
.module {
background: linear-gradient(178deg, #356899 7%, #356899 57%, #F4F6F9 94%);
padding: 20rpx;
.module-info {
padding: 20rpx 20rpx 80rpx;
border-radius: 10rpx;
min-height: 100rpx;
font-size: 28rpx;
border-bottom: 2rpx solid #F2F2F2;
background: linear-gradient(215deg, #C7D3E5 8%, rgba(222, 228, 236, 0) 13%), linear-gradient(162deg, #FFFFFF 25%, #E4EFFD 106%);
position: relative;
border-top-right-radius: 100rpx;
.product-img {
position: absolute;
right: 0rpx;
top: 0;
width: 100rpx;
height: 100rpx;
}
.product-status {
width: 140rpx;
border-radius: 10rpx;
text-align: center;
padding: 8rpx 12rpx;
&.had {
background: #E8FFEA;
color: #00B42A;
}
&.unhad {
background: #FFF7E8;
color: #FF7D00;
}
}
.product-item {
margin: 20rpx 0;
display: flex;
align-items: center;
color: #737D88
}
.product-row {
margin: 20rpx 0;
display: flex;
flex-direction: row;
justify-content: space-between;
color: #737D88;
.row-item {
flex: 1;
.label {
margin-bottom: 10rpx;
}
.val {
color: #1D2129;
&.high-color {
color: #00B42A
}
}
}
}
.finish {
position: absolute;
right: 40rpx;
bottom: 30rpx;
background: linear-gradient(142deg, #FEB34A 14%, #FE9B12 83%);
color: #fff;
width: 200rpx;
text-align: center;
padding: 10rpx;
border-radius: 31rpx;
display: flex;
align-items: center;
justify-content: center;
.complate-img {
width: 30rpx;
height: 30rpx;
margin-right: 10rpx;
}
}
}
}
.module-list {
padding: 20rpx 20rpx;
// box-shadow: 0px 0px 8px 0px rgba(161, 161, 177, 0.12);
.module-title {
color: #0D0D26;
font-size: 36rpx;
margin: 20rpx 0;
font-weight: 500;
}
.history-list {
display: flex;
flex-direction: column;
align-items: center;
min-height: 200rpx;
justify-content: center;
padding: 0rpx 10rpx;
.item {
margin: 10rpx 0;
background: #EAEEF4;
font-size: 28rpx;
padding: 20rpx;
width: 100%;
border-radius: 10rpx;
color: #737D88;
position: relative;
.product-item {
margin: 10rpx 0;
.hight-color {
color: #00B42A;
}
}
.product-row {
margin: 20rpx 0;
display: flex;
flex-direction: row;
justify-content: space-between;
color: #737D88;
.row-item {
flex: 1;
display: flex;
flex-direction: row;
.label {
margin-bottom: 10rpx;
&.high-color {
color: #00B42A
}
}
.val {
color: #1D2129;
&.high-color {
color: #00B42A
}
}
}
}
.tip-index {
position: absolute;
top: 0rpx;
right: 0rpx;
.icon-status {
width: 100rpx;
height: 72rpx;
z-index: 1;
}
.text {
color: #fff;
position: absolute;
top: 4rpx;
right: 30rpx;
z-index: 2;
}
}
}
.no-data {
font-size: 28rpx;
color: #444;
}
}
.table-cont {
font-size: 24rpx;
}
.button {
color: #356899;
}
}
.action {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0rpx;
border-radius: 18rpx;
padding: 30rpx 30rpx;
background: #FFFFFF;
margin: 0 auto;
width: 100vw;
box-shadow: 0px -4px 10px 0px rgba(121, 153, 183, 0.2);
.action-item {
width: 272rpx;
height: 86rpx;
display: flex;
justify-content: center;
align-items: center;
margin: 0 20rpx;
font-size: 40rpx;
color: #fff;
width: 272rpx;
height: 86rpx;
border-radius: 24rpx;
&.info {
background: linear-gradient(157deg, #A9A9A9 -3%, #A9A9A9 90%);
}
&.start {
background: linear-gradient(157deg, #2EACE6 -3%, #356899 90%);
}
&.stop {
background: linear-gradient(167deg, #FEA97B -2%, #F75E40 87%);
}
&.danger {
background: linear-gradient(167deg, #C00000 -2%, #E80000 87%);
}
&.finish {
background: linear-gradient(142deg, #FEB34A 14%, #FE9B12 83%);
}
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
.popup {
.title {
line-height: 1;
padding: 40rpx;
font-size: 32rpx;
font-weight: normal;
border-bottom: 1rpx solid #ddd;
color: #444;
.close {
position: absolute;
right: 24rpx;
top: 40rpx;
height: 60rpx;
width: 60rpx;
text-align: center;
}
}
.cont {
display: flex;
flex-direction: column;
align-items: center;
margin: 40rpx;
height: 50vh;
.item {
display: flex;
align-items: center;
margin: 20rpx 0;
color: #737D88;
width: 94%;
.label {
font-size: 32rpx;
width: 260rpx;
.star {
color: red
}
}
.val {
flex: 1;
font-size: 32rpx;
}
.unit {
width: 100rpx;
margin-left: 4rpx;
text-align: center;
}
}
}
.ok {
font-size: 32rpx;
margin: 20rpx auto 80rpx;
text-align: center;
width: 200rpx;
border-radius: 10rpx;
padding: 8rpx 0;
background-color: #3C8AF7;
color: #fff;
}
}
}
</style>

View File

@ -0,0 +1,185 @@
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import dataItem from './components/dataItem.vue'
import detailPanel from './components/detailPanel.vue'
const childRef = ref(null);
// tabs
const orderTabs = ref([
{ orderState: '0', title: '未确认', isRender: false },
{ orderState: '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) => {
if (options.state) {
//
orderTabs.value.forEach((e, index) => {
e.isRender = e.orderState == options.state
if (e.isRender) {
activeIndex.value = index
}
})
} else {
orderTabs.value.forEach((e, index) => {
e.isRender = e.orderState == '0'
if (e.isRender) {
activeIndex.value = index
}
})
}
})
const btnTop = ref(100)
const btnLeft = ref(20)
const startX = ref(0)
const startY = ref(0)
const isShowPop = ref(false)
//
const handleAdd = () => {
popup.value?.open()
isShowPop.value = true
}
// uni-ui ref
const popup = ref<{
open: (type?: UniHelper.UniPopupType) => void
close: () => void
}>()
const handlePopClose = (flag) => {
popup.value?.close()
isShowPop.value = false
flag && childRef.value[0].updateData()
}
</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 ref="childRef" v-if="item.isRender" :order-state="item.orderState" />
</swiper-item>
</swiper>
<!-- uni-ui 弹出层 -->
<uni-popup ref="popup" :mask-click="false" type="bottom" background-color="#fff">
<detailPanel v-if="isShowPop" @close="handlePopClose" />
</uni-popup>
</view>
</template>
<style lang="scss">
page {
height: 100%;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
position: reactive;
// 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;
}
.float-btn {
position: absolute;
color: #fff;
text-align: center;
.add {
width: 120rpx;
height: 120rpx;
}
}
}
</style>

View File

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

View File

@ -24,6 +24,13 @@ export const countUnqualifiedNotification = (data: Object) => {
data,
})
}
export const countUnqualifiedNotificationConfirm = (data: Object) => {
return http<any[]>({
method: 'GET',
url: '/heli/unqualified-notification/countWx1',
data,
})
}
export const getUnreadMessage = () => {
return http<CategoryItem[]>({
method: 'GET',

View File

@ -31,7 +31,13 @@ export const operateWx = (data: Object) => {
data,
})
}
export const confirm = (data: Object) => {
return http<any[]>({
method: 'POST',
url: '/heli/unqualified-notification/confirm',
data,
})
}
// 获取零件分页
@ -76,3 +82,11 @@ export const postAddWxAPI = (data: Object) => {
data,
})
}
// 品质异常确认分页查询
export const getNotificationConfirmPageAPI = (data: Object) => {
return http<any[]>({
method: 'GET',
url: '/heli/unqualified-notification/unqualifiedNotificationConfirmPageWx',
data,
})
}