Commit 53185b82 by pangchong

feat: 工作反馈

parent e50ee0c4
import { http } from 'mocp/utils/http'
export const getArrangeWorkListApi = (data, config) => {
return http({
method: 'POST',
url: '/technical-support/getArrangeWorkList',
data,
config
})
}
export const getArrangeWorkDetailApi = (data, config) => {
return http({
method: 'POST',
url: '/technical-support/getArrangeWorkDetail',
data,
config
})
}
export const savaArrangeWorkFeedbackApi = (data, config) => {
return http({
method: 'POST',
url: '/technical-support/savaArrangeWorkFeedback',
data,
config
})
}
......@@ -24,3 +24,11 @@ export const getAdminListApi = (data, config) => {
config
})
}
export const getBasicParamsListApi = (data, config) => {
return http({
method: 'POST',
url: '/resource/getBasicParamsList',
data,
config
})
}
......@@ -64,7 +64,7 @@ const ps = defineProps({
},
format: {
type: String,
default: 'YYYY-MM-DD'
default: 'YYYY/MM/DD'
},
cancelText: {
type: String,
......
......@@ -113,14 +113,16 @@ const queryList = (pageIndex, pageSize) => {
}
const params = {
pageIndex,
pageSize,
[ps.tabValueField]: ps.tabValue
pageSize
}
if (ps.tabValue) {
params[ps.tabValueField] = ps.tabValue
}
if (Object.prototype.toString.call(ps.api) == '[object Function]') {
ps.api(params, { loading: true })
.then((res) => {
if (res.code == 200) {
paging.value?.complete(res.list || [])
paging.value?.complete(res.list || res.data?.list || [])
firstLoaded.value = true
} else {
uni.$mocpMessage.showToast(res.message)
......@@ -138,6 +140,9 @@ const queryList = (pageIndex, pageSize) => {
defineExpose({
reload: () => {
paging.value?.reload()
},
updateCache: () => {
paging.value?.updateCache()
}
})
</script>
......
......@@ -188,6 +188,9 @@ const pagingArr = ref([])
defineExpose({
reload: () => {
pagingArr.value[current.value]?.reload()
},
updateCache: () => {
pagingArr.value[current.value]?.updateCache()
}
})
</script>
......
......@@ -15,3 +15,11 @@ export const eventType = [
{ label: '扣分', value: 0 },
{ label: '加分', value: 1 }
]
export const feedbackOpts = [
{ label: '是', value: 1 },
{ label: '落实执行', value: 0 }
]
export const feedbackState = [
{ label: 'OPEN', value: 1 },
{ label: 'CLOSE', value: 2 }
]
......@@ -14,15 +14,15 @@
<slot name="title" v-if="title">
<view class="title">{{ title }}</view>
</slot>
<view class="content">
<scroll-view scroll-y class="content" :scroll-top="scrollTop" @scroll="scroll">
<slot></slot>
</view>
</scroll-view>
</view>
</up-popup>
</template>
<script setup>
import { computed } from 'vue'
import { computed, nextTick, ref, watch } from 'vue'
const es = defineEmits(['close', 'open'])
const ps = defineProps({
......@@ -89,6 +89,23 @@ const getCustomStyle = computed(() => {
}
return style
})
//控制滚动区域
const scrollTop = ref(0)
const oldScrollTop = ref(0)
const scroll = (e) => {
oldScrollTop.value = e.detail.scrollTop
}
watch(
() => ps.modelValue,
(value) => {
if (value) {
scrollTop.value = 0
nextTick(() => {
scrollTop.value = oldScrollTop.value
})
}
}
)
const close = () => {
es('close', false)
}
......
......@@ -39,7 +39,7 @@ const ps = defineProps({
},
url: {
type: String,
default: ''
default: '/resource/uploadFile'
},
uploadIcon: {
type: String,
......
......@@ -32,7 +32,6 @@ const useAppraisalRecordStore = defineStore('appraisalRecord', {
if (res.code == 200) {
this.details = res.data
this.details.file = JSON.parse(res.data.file)
this.details.eventTime = String(res.data.eventTime)
} else {
uni.$mocpMessage.showToast(res.message)
}
......
import { getArrangeWorkDetailApi } from 'mocp/api/assign-work'
import { defineStore } from 'pinia'
const useAssignWorkStore = defineStore('assignWork', {
state: () => {
return {
id: '',
details: undefined,
arrangeWorkExtendList: [], //责任单位列表
arrangeWorkExtend: undefined //当前选中的责任单位
}
},
getters: {
//获取分解计划
getDecompose(state) {
return JSON.parse(state.arrangeWorkExtend?.decompose || '[]') || []
}
},
actions: {
async getArrangeWorkDetail() {
const res = await getArrangeWorkDetailApi({ id: this.id }, { loading: true })
if (res.code == 200) {
this.details = res.data
this.arrangeWorkExtendList = res.data.arrangeWorkExtendList || []
this.arrangeWorkExtend = res.data.arrangeWorkExtendList[0]
} else {
uni.$mocpMessage.showToast(res.message)
}
},
setState(...args) {
this.$patch({ [args[0]]: args[1] })
}
},
// 配置持久化
persist: {
// 调整为兼容多端的API
storage: {
setItem(key, value) {
uni.setStorageSync(key, value)
},
getItem(key) {
return uni.getStorageSync(key)
}
}
}
})
export default useAssignWorkStore
import { getAircraftNumbersApi } from 'mocp/api/base'
import { getAircraftNumbersApi, getBasicParamsListApi } from 'mocp/api/base'
import { defineStore } from 'pinia'
const useBaseStore = defineStore('base', {
......@@ -6,19 +6,56 @@ const useBaseStore = defineStore('base', {
return {
selectList: {
deviceNumSelect: [] //机号
}
},
allBasicParams: {}
}
},
getters: {},
actions: {
initSysData() {
this.getAircraftNumbers()
this.getBasicParamsList()
},
async getAircraftNumbers() {
const res = await getAircraftNumbersApi({})
if (res.code == 200) {
this.selectList.deviceNumSelect = res.data
}
},
async getBasicParamsList() {
const res = await getBasicParamsListApi({})
if (res.code == 200) {
this.allBasicParams = res.data.reduce((q, w) => {
if (!q[w.paramType]) {
q[w.paramType] = []
}
q[w.paramType].push(w)
return q
}, {})
}
},
getParamsByType(paramType) {
return this.allBasicParams[paramType]
.filter((item) => item.isDel == 0)
.map((item) => {
return { label: item.paramName, value: item.paramCode }
})
},
getParamNameByValue(paramType, paramName) {
return this.getParamsByType(paramType).find((item) => item.value == paramName)?.label || ''
}
},
// 配置持久化
persist: false
persist: {
// 调整为兼容多端的API
storage: {
setItem(key, value) {
uni.setStorageSync(key, value)
},
getItem(key) {
return uni.getStorageSync(key)
}
}
}
})
export default useBaseStore
......@@ -45,7 +45,7 @@ const httpInterceptor = (options) => {
options.data = {
...options.data,
apiPwd: 'Ifar$2_0160_525_Mocp',
requestFrom: '3',
requestFrom: '6',
realUserId: userStore.userInfo?.id
}
}
......
......@@ -10,6 +10,6 @@ export const timeStampFormat = (timeStamp, opt) => {
return ''
}
timeStamp = parseInt(String(timeStamp))
const format = opt?.format || 'YYYY-MM-DD HH:mm:ss'
const format = opt?.format || 'YYYY/MM/DD'
return Day(timeStamp).format(format)
}
......@@ -25,7 +25,7 @@
</view>
<view class="label">
<global-icon icon="calendar" color="#1D2129"></global-icon>
<text class="txt">{{ calendar != -1 ? timeStampFormat(calendar) : '-' }}</text>
<text class="txt">{{ calendar != -1 ? timeStampFormat(calendar, { format: 'YYYY/MM/DD HH:mm:ss' }) : '-' }}</text>
</view>
</view>
</slot>
......
import { reactive, ref } from 'vue'
export const formRef = ref()
......
......@@ -16,7 +16,7 @@
<global-icon class="left-icon" icon="Vector" size="24" color="#DD4012"></global-icon>
<view class="txt">{{ details.ac }} {{ details.acType }}</view>
</view>
<view class="right">{{ timeStampFormat(details.eventTime, { format: 'YYYY-MM-DD' }) }}</view>
<view class="right">{{ timeStampFormat(details.eventTime) }}</view>
</view>
</view>
<view class="details-body">
......
......@@ -119,7 +119,7 @@
<global-picker pickAlign="right" dictkey="appealInfo" v-model="formData.appealInfo" clearable></global-picker>
</view>
<view class="appeal-content">
<global-upload :fileList="getFileList" url="/resource/uploadFile" @handleUpload="handleUpload"></global-upload>
<global-upload :fileList="getFileList" @handleUpload="handleUpload"></global-upload>
</view>
</view>
</view>
......@@ -159,7 +159,7 @@ onShow(() => {
formData.dmUid = details.value.dmUid
formData.eventMsg = details.value.eventMsg
formData.eventSource = details.value.eventSource
formData.eventTime = details.value.eventTime
formData.eventTime = String(details.value.eventTime)
formData.eventType = details.value.eventType
formData.examineBasis = details.value.examineBasis
formData.examineType = details.value.examineType
......
......@@ -34,7 +34,6 @@ const ps = defineProps({
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 0;
border-bottom: 2rpx solid #f4f4f4;
margin-top: 16rpx;
}
</style>
<template>
<view class="card-details-item">
<view class="card-details-item" :class="{ borderBottom }">
<view class="title" v-if="title">{{ title }}</view>
<view class="label" v-if="label">{{ label }}</view>
<view class="content">{{ content }}</view>
<slot></slot>
</view>
</template>
<script setup>
const ps = defineProps({
borderBottom: {
type: Boolean,
default: true
},
title: {
type: String,
default: ''
......@@ -24,8 +29,11 @@ const ps = defineProps({
</script>
<style lang="scss" scoped>
.card-details-item {
border-bottom: 2rpx solid #f4f4f4;
padding: 16rpx 0;
padding-top: 16rpx;
&.borderBottom {
padding-bottom: 16rpx;
border-bottom: 2rpx solid #f4f4f4;
}
.title {
font-size: 34rpx;
color: $mocp-text-5;
......
<template>
<global-popup v-model="showPopup" mode="right" :width="580" background="#F7F8FA" title="选择责任单位" :round="32" @close="showPopup = false">
<view class="list">
<view class="item" v-for="item in 100" :key="item" @tap="handleClick">中南维修基地</view>
<view class="item" v-for="item in arrangeWorkExtendList" :key="item.id" @tap="handleClick(item)">
{{ item.companyFullName }}
</view>
</view>
</global-popup>
</template>
<script setup>
import { ref } from 'vue'
import useAssignWorkStore from 'mocp/store/assign-work'
import { storeToRefs } from 'pinia'
const assignWorkStore = useAssignWorkStore()
const { arrangeWorkExtendList } = storeToRefs(assignWorkStore)
const showPopup = ref(false)
const open = () => {
showPopup.value = true
}
//切换责任公司
const handleClick = () => {
const handleClick = (row) => {
showPopup.value = false
assignWorkStore.setState('arrangeWorkExtend', row)
uni.$mocpMessage.showToast('已切换成' + row.companyFullName)
}
defineExpose({
open
......
......@@ -3,6 +3,11 @@
color: $mocp-text-4;
background: #fff;
&-header {
&-title {
font-size: 48rpx;
color: $mocp-text-5;
margin-bottom: 16rpx;
}
&-top {
display: flex;
align-items: center;
......@@ -16,9 +21,6 @@
}
}
&-center {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 16rpx;
.left {
.txt {
......@@ -26,6 +28,10 @@
}
}
.right {
margin-top: 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
.txt {
margin-left: 16rpx;
}
......
import { reactive, ref } from 'vue'
export const fileVoList = ref([]) //分解计划文件
export const approvalFileVoList = ref([]) //工作反馈文件
export const formData = reactive({
problem: '',
workTarget: '',
current: '',
baseApprovalLeader: '',
mcdApprovalLeader: '',
followUpFeedback: '0',
pcTime: null,
feedbackState: null,
feedbackUser: '',
feedbackTime: ''
})
export const rules = reactive({
feedbackState: [
{
type: 'number',
required: true,
message: '请选择工作反馈状态',
trigger: ['blur', 'change']
}
],
problem: [
{
required: true,
message: '请输入问题分析',
trigger: ['blur', 'change']
}
],
workTarget: [
{
required: true,
message: '请输入解决措施',
trigger: ['blur', 'change']
}
],
current: [
{
required: true,
message: '请输入当前进展',
trigger: ['blur', 'change']
}
],
baseApprovalLeader: [
{
required: true,
message: '请输入基地/部门批准领导',
trigger: ['blur', 'change']
}
],
mcdApprovalLeader: [
{
required: true,
message: 'MCD批准领导',
trigger: ['blur', 'change']
}
],
followUpFeedback: [
{
required: true,
message: '请选择后续措施反馈',
trigger: ['blur', 'change']
}
],
pcTime: [
{
type: 'number',
required: true,
message: '请选择计划完成时间',
trigger: ['blur', 'change']
}
]
})
import { approvalFileVoList, fileVoList } from './edit-work.compositions'
export const handleUploadFile = (data) => {
fileVoList.value = data
}
export const handleUploadApproval = (data) => {
approvalFileVoList.value = data
}
......@@ -33,13 +33,10 @@
line-height: 40rpx;
}
&-footer {
margin-top: 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
.label {
display: flex;
align-items: center;
margin-top: 16rpx;
.txt {
margin-left: 16rpx;
}
......
<template>
<global-page
:padding="24"
title="早会工作详情"
showNavRight
:title="arrangeWorkExtend?.companyFullName"
:showNavRight="arrangeWorkExtendList.length"
navRightType="icon"
showFooterBtn
footerBtnText="工作反馈"
:editMode="3"
@handleRightClick="handleRightClick"
@handleFooterClick="handleFooterClick"
>
<view class="details">
<view class="details" v-if="details">
<view class="details-header">
<view class="details-header-title">{{ baseStore.getParamNameByValue('LayoutWorkType', details.workType) }}详情</view>
<view class="details-header-top">
<view class="left">CLOSE</view>
<view class="left">{{ details.state == 1 ? 'OPEN' : 'ClOSE' }}</view>
<view class="right">
<global-field label="提出人:" value="唐恒山"></global-field>
<global-field label="提出人:" :value="details.presenter"></global-field>
</view>
</view>
<view class="details-header-center">
<view class="left">
<global-icon icon="mind-mapping"></global-icon>
<global-field class="txt" label="工作台编号:" value="24242424"></global-field>
<global-field class="txt" label="工作台编号:" :value="details.workbench || '-'"></global-field>
</view>
<view class="right">
<text>陈朝丽测试</text>
<text class="txt">早会工作</text>
<text>{{ details.seat }}</text>
<text class="txt">{{ baseStore.getParamNameByValue('LayoutWorkType', details.workType) }}</text>
</view>
</view>
<view class="details-header-footer">
......@@ -33,47 +33,72 @@
<global-icon icon="safe"></global-icon>
<text class="txt">反馈情况</text>
</view>
<view class="right"></view>
<view class="right">{{ useGetDictByValue('feedbackOpts', details.feedback) }}</view>
</view>
</view>
<view class="details-body">
<view class="details-body-content">
针对股份1213飞机1月2日海口过站检查发现副驾驶氧气面罩盒测试电门损坏的情况,要求737机型中心分析原因。
{{ details.taskDescribe }}
</view>
<view class="details-body-file">
<image src="/static/mocp/image/login/upload.png" alt="" mode="widthFix" />
<global-album :fileList="details.taskFileVoList"></global-album>
</view>
</view>
<view class="details-footer">
<global-field label="开始日期:" value="2024-01-03"></global-field>
<global-field label="完成日期:" value="2024-01-03"></global-field>
<global-field label="开始日期:" :value="timeStampFormat(details.startTime)"></global-field>
<global-field label="完成日期:" :value="timeStampFormat(details.feedbackTime)"></global-field>
</view>
</view>
<card-details title="工作反馈">
<card-details-item
title="问题分析"
content="首航B6867飞机1月1日海口过站机组反映绿系统液压油量低,隔离发现PTU总管1113GM上管"
></card-details-item>
<card-details-item title="解决措施" label="工作目标" content="一、 工作目标 分析6867飞机渗漏原因,视情采"></card-details-item>
<card-details-item
label="分解计划"
content="二、 任务分解 1. B6867飞机绿系统液压油量低的原因隔离PTU总管上液压管路远端接头松动导致,对该松动接头重新磅力后,检查不漏; 2. 查询B6867飞机PTU总管为2013年4月2日装机,为原始装机件,查询漏油管路没有更换记录,判断同为原始装机件; 3. 松动接头位于起落架舱内,接头处于长时间液压冲击和飞机轮舱收放起落架时高振动环境中,导致此接头螺纹松动; 4. 经查询,此接头渗漏为A320机队首例,判断为突发个例。B6867飞
"
></card-details-item>
<card-details-footer rightLabel="完成时限:" rightValue="2024-01-03"></card-details-footer>
<card-details-item
label="当前进展"
content="三、 当前进展 1. 针对液压部件和液压管漏油的问题,TS已编写《EO-A32-29-2021-008详细检查A32液压部件及管路》,对机队液压部件、管路及管接头进行1000FH/180D的重复性查;(2)A320机队中心已编写《A320系列液压油漏油标准》,供快速处置时参考;在冬季维护时加强对易漏油部件的检查,封圈老化判断方法已有培训材料,帮助一线检查判断;(3)A320机队中心已编写《SOP-A32-00-002 A32飞机漏油故障的标准处置流程》,提高处置效率。
"
></card-details-item>
<card-details-footer leftLabel="基地/部门批准领导:" leftValue="测试" rightLabel="MCD批准领导:" rightValue="测试"></card-details-footer>
<!-- <view class="card-empty">
<global-empty></global-empty>
</view> -->
</card-details>
<card-details title="领导批示" titleIcon="drive">
<view class="card-empty">
<global-empty></global-empty>
</view>
</card-details>
<template v-if="arrangeWorkExtend">
<card-details title="工作反馈">
<template v-if="arrangeWorkExtend.feedbackTime != 0">
<card-details-item title="问题分析" :content="arrangeWorkExtend.problem"></card-details-item>
<card-details-item title="解决措施" label="工作目标" :content="arrangeWorkExtend.workTarget"></card-details-item>
<template v-for="(item, index) in assignWorkStore.getDecompose" :key="index">
<card-details-item
:label="assignWorkStore.getDecompose.length > 1 ? '分解计划' + (index + 1) : '分解计划'"
:content="item.plan"
>
<card-details-footer rightLabel="完成时限:" :rightValue="timeStampFormat(item.time) || '-'"></card-details-footer>
</card-details-item>
</template>
<card-details-item label="当前进展" :content="arrangeWorkExtend.current">
<global-album :fileList="arrangeWorkExtend.fileVoList"></global-album>
</card-details-item>
<card-details-item>
<card-details-footer leftLabel="基地/部门批准领导:" :leftValue="arrangeWorkExtend.baseApprovalLeader"></card-details-footer>
<card-details-footer leftLabel="MCD批准领导:" :leftValue="arrangeWorkExtend.mcdApprovalLeader"></card-details-footer>
</card-details-item>
<card-details-item label="批复附件" :borderBottom="false">
<global-album :fileList="arrangeWorkExtend.approvalFileVoList"></global-album>
<card-details-footer
leftLabel="后续措施反馈:"
:leftValue="arrangeWorkExtend.followUpFeedback == '1' ? '是' : '否'"
rightLabel="计划完成时间:"
:rightValue="arrangeWorkExtend.followUpFeedback == '1' ? timeStampFormat(arrangeWorkExtend.pcTime) : '-'"
></card-details-footer>
<card-details-footer
leftLabel="工作反馈状态:"
:leftValue="useGetDictByValue('feedbackState', arrangeWorkExtend.feedbackState)"
rightLabel="反馈人:"
:rightValue="arrangeWorkExtend.feedbackUser || '-'"
></card-details-footer>
<card-details-footer
leftLabel="反馈时间:"
:leftValue="timeStampFormat(arrangeWorkExtend.feedbackTime) || '-'"
></card-details-footer>
</card-details-item>
</template>
<view class="card-empty" v-else>
<global-empty></global-empty>
</view>
</card-details>
<card-details title="领导批示" titleIcon="drive">
<view class="card-empty">
<global-empty></global-empty>
</view>
</card-details>
</template>
</global-page>
<!-- 责任单位弹出层 -->
<company-popup ref="companyPopupRef"></company-popup>
......@@ -85,7 +110,21 @@ import CardDetails from './components/card-details.vue'
import CardDetailsItem from './components/card-details-item.vue'
import CardDetailsFooter from './components/card-details-footer.vue'
import CompanyPopup from './components/company-popup.vue'
import useAssignWorkStore from 'mocp/store/assign-work'
import { storeToRefs } from 'pinia'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import useBaseStore from 'mocp/store/base'
import { timeStampFormat } from 'mocp/utils/tool'
import { useGetDictByValue } from 'mocp/components/global-picker/useDict'
const baseStore = useBaseStore()
const query = defineProps(['id'])
const assignWorkStore = useAssignWorkStore()
const { details, arrangeWorkExtendList, arrangeWorkExtend } = storeToRefs(assignWorkStore)
onLoad(() => {
assignWorkStore.setState('id', query.id)
assignWorkStore.getArrangeWorkDetail()
})
//责任公司弹框
const companyPopupRef = ref()
const handleRightClick = () => {
......@@ -95,6 +134,9 @@ const handleRightClick = () => {
const handleFooterClick = () => {
uni.$mocpJump.navigateTo('/panel/assign-work/edit-work')
}
onUnload(() => {
assignWorkStore.$reset()
})
</script>
<style lang="scss" scoped>
@import './constants/details.scss';
......
......@@ -5,38 +5,36 @@
:showNavRight="true"
navRightType="button"
navRightText="保存"
@handleRightClick="handleSave"
showFooterBtn
footerBtnText="添加分解计划"
@handleFooterClick="handleFooterClick"
>
<view class="mocp-form">
<up-form labelPosition="left" labelWidth="auto" ref="formRef">
<view class="form">
<up-form-item label="分解计划1" :borderBottom="true" labelPosition="top">
<view class="delete" @tap="handleDelete"><global-icon icon="delete-01" color="#F53F3F"></global-icon></view>
<up-textarea
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<up-form-item label="完成时限" :borderBottom="true">
<global-date pickAlign="right" clearable :emptyValue="-1" placeholder="请选择日期"></global-date>
</up-form-item>
</view>
<view class="form">
<up-form-item label="分解计划2" :borderBottom="true" labelPosition="top">
<view class="delete" @tap="handleDelete"><global-icon icon="delete-01" color="#F53F3F"></global-icon></view>
<up-textarea
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<up-form-item label="完成时限" :borderBottom="true">
<global-date pickAlign="right" clearable :emptyValue="-1" placeholder="请选择日期"></global-date>
</up-form-item>
</view>
<up-form labelPosition="left" labelWidth="auto">
<template v-for="(item, index) in formData" :key="index">
<view class="form">
<up-form-item
:label="formData.length > 1 ? '分解计划' + (index + 1) : '分解计划'"
:borderBottom="true"
labelPosition="top"
required
>
<view class="delete" v-if="formData.length > 1" @tap="handleDelete(index)">
<global-icon icon="delete-01" color="#F53F3F"></global-icon>
</view>
<up-textarea
v-model="item.plan"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<up-form-item label="完成时限" :borderBottom="true">
<global-date pickAlign="right" clearable placeholder="请选择日期" v-model="item.time" emptyValue="null"></global-date>
</up-form-item>
</view>
</template>
</up-form>
</view>
<up-modal
......@@ -54,14 +52,45 @@
<script setup>
import { ref } from 'vue'
import { cloneDeep } from 'lodash'
const formData = ref([])
//初始化数据
uni.$on('sendDecompose', (data) => {
if (data.length) {
formData.value = cloneDeep(data)
} else {
formData.value.push({ plan: '', time: null })
}
})
const show = ref(false)
const handleDelete = () => {
const currentIndex = ref(-1)
//删除
const handleDelete = (index) => {
show.value = true
currentIndex.value = index
}
//确认删除
const confirm = () => {
formData.value.splice(currentIndex.value, 1)
show.value = false
currentIndex.value = -1
}
//保存
const handleSave = async () => {
const planIndex = formData.value.findIndex((item) => item.plan.trim() === '')
if (planIndex > -1) {
if (formData.value.length > 1) {
return uni.$mocpMessage.showToast(`请输入分解计划${planIndex + 1}的内容`)
} else {
return uni.$mocpMessage.showToast(`请输入分解计划的内容`)
}
}
uni.$emit('changeDecompose', formData.value)
uni.$mocpJump.navigateBack()
}
const confirm = () => {}
const handleFooterClick = () => {
console.log('点击了添加分解计划')
formData.value.push({ plan: '', time: null })
}
</script>
<style lang="scss" scoped>
......
......@@ -11,7 +11,7 @@
</up-form-item>
<up-form-item label="验证材料" labelPosition="top" :borderBottom="true">
<view style="margin-top: 24rpx">
<global-upload url="/resource/uploadFile"></global-upload>
<global-upload></global-upload>
</view>
</up-form-item>
<up-form-item label="应用分类" :borderBottom="true">
......
......@@ -17,7 +17,7 @@
</up-form-item>
<up-form-item label="验证附件" labelPosition="top" :borderBottom="true">
<view style="margin-top: 24rpx">
<global-upload url="/resource/uploadFile"></global-upload>
<global-upload></global-upload>
</view>
</up-form-item>
<up-form-item label="工作验证状态" :borderBottom="true">
......
<template>
<global-page title="添加工作反馈" navLeftType="text" :showNavRight="true" navRightType="button" navRightText="保存">
<global-page
title="添加工作反馈"
navLeftType="text"
:showNavRight="true"
navRightType="button"
navRightText="保存"
@handleRightClick="handleSave"
>
<view class="mocp-form">
<up-form labelPosition="left" labelWidth="auto" ref="formRef">
<up-form labelPosition="left" labelWidth="auto" :model="formData" :rules="rules" ref="formRef">
<view class="form">
<view class="form-item">
<up-form-item label="工作反馈状态" :borderBottom="true">
<global-picker pickAlign="right" clearable></global-picker>
<up-form-item label="工作反馈状态" :borderBottom="true" prop="feedbackState" required>
<global-picker v-model="formData.feedbackState" pickAlign="right" clearable dictkey="feedbackState"></global-picker>
</up-form-item>
<up-form-item label="问题分析" :borderBottom="true" labelPosition="top">
<up-form-item label="问题分析" :borderBottom="true" labelPosition="top" prop="problem" required>
<up-textarea
v-model="formData.problem"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
......@@ -19,8 +27,13 @@
<view class="form">
<view class="form-title">解决措施</view>
<view class="form-item">
<up-form-item label="工作目标" :borderBottom="true" labelPosition="top">
<view class="textarea">一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容</view>
<up-form-item label="工作目标" :borderBottom="true" labelPosition="top" prop="workTarget" required>
<up-textarea
v-model="formData.workTarget"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<view class="plan">
<view class="plan-title">
......@@ -32,26 +45,28 @@
</view>
<view class="plan-body">
<view class="plan-body-list">
<view class="plan-body-item">
<view class="plan-body-title">
<view class="left">分解计划1</view>
<view class="right">2023-11-27</view>
<template v-for="(item, index) in decompose" :key="index">
<view class="plan-body-item">
<view class="plan-body-title">
<view class="left">
{{ decompose.length > 1 ? '分解计划' + (index + 1) : '分解计划' }}
</view>
<view class="right">{{ timeStampFormat(item.time) }}</view>
</view>
<view class="plan-body-text">{{ item.plan }}</view>
</view>
<view class="plan-body-text">一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容</view>
</view>
<view class="plan-body-item">
<view class="plan-body-title">
<view class="left">分解计划2</view>
<view class="right">2023-11-27</view>
</view>
<view class="plan-body-text">一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容</view>
</view>
</template>
</view>
<up-form-item label="当前进展" :borderBottom="true" labelPosition="top">
<view class="textarea">一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容</view>
<up-form-item label="当前进展" :borderBottom="true" labelPosition="top" prop="current" required>
<up-textarea
v-model="formData.current"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<up-form-item :borderBottom="true">
<global-upload url="/resource/uploadFile"></global-upload>
<global-upload :fileList="arrangeWorkExtend.fileVoList" @handleUpload="handleUploadFile"></global-upload>
</up-form-item>
</view>
</view>
......@@ -60,24 +75,38 @@
<view class="form">
<view class="form-title" style="padding: 12rpx"></view>
<view class="form-item">
<up-form-item label="基地/部门批准领导" :borderBottom="true">
<up-input border="none" inputAlign="right" placeholder="请输入" :adjustPosition="false" clearable></up-input>
<up-form-item label="基地/部门批准领导" :borderBottom="true" prop="baseApprovalLeader" required>
<up-input
v-model="formData.baseApprovalLeader"
border="none"
inputAlign="right"
placeholder="请输入"
:adjustPosition="false"
clearable
></up-input>
</up-form-item>
<up-form-item label="MCD批准领导" :borderBottom="true">
<up-input border="none" inputAlign="right" placeholder="请输入" :adjustPosition="false" clearable></up-input>
<up-form-item label="MCD批准领导" :borderBottom="true" prop="mcdApprovalLeader" required>
<up-input
v-model="formData.mcdApprovalLeader"
border="none"
inputAlign="right"
placeholder="请输入"
:adjustPosition="false"
clearable
></up-input>
</up-form-item>
<up-form-item label="批复附件" labelPosition="top" :borderBottom="true">
<view style="margin-top: 24rpx">
<global-upload url="/resource/uploadFile"></global-upload>
<global-upload :fileList="arrangeWorkExtend.approvalFileVoList" @handleUpload="handleUploadApproval"></global-upload>
</view>
</up-form-item>
<up-form-item label="后续措施反馈" :borderBottom="true">
<up-form-item label="后续措施反馈" :borderBottom="true" required>
<view class="switch">
<up-switch v-model="value" @change="change"></up-switch>
<up-switch v-model="formData.followUpFeedback" activeValue="1" inactiveValue="0"></up-switch>
</view>
</up-form-item>
<up-form-item label="计划完成时间" :borderBottom="true">
<global-date pickAlign="right" clearable :emptyValue="-1" placeholder="请选择日期"></global-date>
<up-form-item label="计划完成时间" :borderBottom="true" v-if="formData.followUpFeedback == 1" prop="pcTime" required>
<global-date v-model="formData.pcTime" pickAlign="right" clearable placeholder="请选择日期"></global-date>
</up-form-item>
</view>
</view>
......@@ -87,15 +116,77 @@
</template>
<script setup>
import useAssignWorkStore from 'mocp/store/assign-work'
import { storeToRefs } from 'pinia'
import { formData, rules } from './constants/edit-work.compositions'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import { handleUploadApproval, handleUploadFile } from './constants/edit-work.functionals'
import { approvalFileVoList, fileVoList } from './constants/edit-work.compositions'
import { timeStampFormat } from 'mocp/utils/tool'
import { ref } from 'vue'
import { cloneDeep } from 'lodash'
import { savaArrangeWorkFeedbackApi } from 'mocp/api/assign-work'
const goTo = () => {
uni.$mocpJump.navigateTo('/panel/assign-work/edit-decompose')
const assignWorkStore = useAssignWorkStore()
const { arrangeWorkExtend } = storeToRefs(assignWorkStore)
const decompose = ref(cloneDeep(assignWorkStore.getDecompose))
// 页面初始化
onLoad(() => {
formData.id = arrangeWorkExtend.value.id
formData.workId = arrangeWorkExtend.value.workId
formData.company = arrangeWorkExtend.value.company
formData.problem = arrangeWorkExtend.value.problem
formData.workTarget = arrangeWorkExtend.value.workTarget
formData.current = arrangeWorkExtend.value.current
formData.baseApprovalLeader = arrangeWorkExtend.value.baseApprovalLeader
formData.mcdApprovalLeader = arrangeWorkExtend.value.mcdApprovalLeader
formData.followUpFeedback = arrangeWorkExtend.value.followUpFeedback || '0'
formData.pcTime = arrangeWorkExtend.value.pcTime
formData.feedbackState = arrangeWorkExtend.value.feedbackState
formData.feedbackUser = arrangeWorkExtend.value.feedbackUser
formData.feedbackTime = arrangeWorkExtend.value.feedbackTime
//初始化文件列表
fileVoList.value = arrangeWorkExtend.value.fileVoList
approvalFileVoList.value = arrangeWorkExtend.value.approvalFileVoList
})
//监听分解计划的变化
uni.$on('changeDecompose', (data) => {
decompose.value = data
})
onUnload(() => {
uni.$off('changeDecompose')
})
//保存
const formRef = ref()
const handleSave = async () => {
await formRef.value?.validate()
if (!decompose.value || decompose.value.length == 0) {
return uni.$mocpMessage.showToast('请添加分解计划')
}
const params = {
...formData,
decompose: JSON.stringify(decompose.value),
approvalFile: approvalFileVoList.value.map((v) => v.id).join(),
file: fileVoList.value.map((v) => v.id).join()
}
if (formData.followUpFeedback == '0') {
params.pcTime = ''
}
const res = await savaArrangeWorkFeedbackApi(params, { loading: true })
if (res.code == 200) {
uni.$mocpJump.navigateBack()
uni.$mocpMessage.showToast(res.message)
//更新当前责任单位详情
assignWorkStore.setState('arrangeWorkExtend', res.data)
} else {
uni.$mocpMessage.showToast(res.message)
}
}
//开关
const value = ref(true)
const change = (e) => {
console.log(e)
//添加分解计划
const goTo = () => {
uni.$mocpJump.navigateTo('/panel/assign-work/edit-decompose').then(() => {
uni.$emit('sendDecompose', decompose.value)
})
}
</script>
<style lang="scss">
......
<template>
<global-page-swiper title="布置工作" refresherEnabled loadingMoreEnabled :tabList="tabList" :api="getRqmListApi" ref="paging" :padding="24">
<global-page-swiper
title="布置工作"
refresherEnabled
loadingMoreEnabled
:tabList="tabList"
:api="getArrangeWorkListApi"
:padding="24"
tabValueField="state"
>
<template #="{ dataList }">
<view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)">
<view class="item-title">
<view class="left">
<view class="type">{{ item.status == 1 ? 'OPEN' : 'ClOSE' }}</view>
<view class="txt">早会工作详情</view>
<view class="type">{{ item.state == 1 ? 'OPEN' : 'ClOSE' }}</view>
<view class="txt u-line-1">{{ baseStore.getParamNameByValue('LayoutWorkType', item.workType) }}详情</view>
</view>
<view class="right">早会工作</view>
<view class="right u-line-1">{{ baseStore.getParamNameByValue('LayoutWorkType', item.workType) }}</view>
</view>
<view class="item-content u-line-3">
海航技术专项布置〔2024〕00022号: 首6709飞机1月10日广州航前有AC ESS
BUSSHED信息,同时左侧MCDU和ND黑屏,断电重启无效,排故所需8XH和9XH继电器集团无料的情况,要求采购管理部对使用及库存情况进行核实,尽快安排采购配备。
{{ item.taskDescribe }}
</view>
<view class="item-footer">
<view class="label">
<global-icon icon="calendar"></global-icon>
<text class="txt">2024-01-10</text>
<text class="txt">
{{ timeStampFormat(item.startTime) }}
-
{{ timeStampFormat(item.feedbackTime) }}
</text>
</view>
<view class="label">
<global-icon icon="idcard"></global-icon>
<text class="txt">陈朝丽测试</text>
<text class="txt">{{ item.presenter }}</text>
</view>
</view>
</view>
......@@ -30,32 +41,20 @@
<script setup>
import { ref } from 'vue'
import { getRqmListApi } from 'mocp/api/appraisal-record'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import useAppraisalRecordStore from 'mocp/store/appraisal-record'
import useBaseStore from 'mocp/store/base'
import { timeStampFormat } from 'mocp/utils/tool'
import { getArrangeWorkListApi } from 'mocp/api/assign-work'
const tabList = ref([
{ name: 'OPEN', value: 1 },
{ name: 'CLOSE', value: 0 },
{ name: '全部', value: -1 }
{ name: 'CLOSE', value: 2 },
{ name: '全部', value: null }
])
const baseStore = useBaseStore()
//跳转
const goDetails = (data) => {
uni.$mocpJump.navigateTo('/panel/assign-work/details', { id: data.id })
}
//加载下拉框数据
const appraisalRecordStore = useAppraisalRecordStore()
onLoad(() => {
appraisalRecordStore.getRqmOptions()
})
//刷新
const paging = ref()
uni.$on('appraisalRecordReload', () => {
paging.value?.reload()
})
onUnload(() => {
uni.$off('appraisalRecordReload')
})
</script>
<style lang="scss" scoped>
@import './constants/list.scss';
......
......@@ -33,7 +33,7 @@
<script setup>
import { ref } from 'vue'
import MenuItem from './components/menu-item.vue'
import MenuItem from './menu-item.vue'
import useUserStore from 'mocp/store/user'
const userStore = useUserStore()
......@@ -59,5 +59,5 @@ const goAppCenter = () => {
}
</script>
<style lang="scss" scoped>
@import './constants/panel-menu.scss';
@import '../constants/panel-menu.scss';
</style>
......@@ -36,5 +36,5 @@
<script setup></script>
<style lang="scss" scoped>
@import './constants/panel-navbar.scss';
@import '../constants/panel-navbar.scss';
</style>
......@@ -11,12 +11,13 @@
</template>
<script setup>
import PanelNavbar from './panel-navbar.vue'
import PanelMenu from './panel-menu.vue'
import PanelNavbar from './components/panel-navbar.vue'
import PanelMenu from './components/panel-menu.vue'
import useBaseStore from 'mocp/store/base'
//加载基础参数
const baseStore = useBaseStore()
baseStore.getAircraftNumbers()
baseStore.initSysData()
</script>
<style lang="scss" scoped>
.page-bg {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment