Commit 85ab23a6 by pangchong

feat: 运行决策开发

parent d0bbbd07
......@@ -26,6 +26,9 @@ declare module 'vue' {
GlobalUploadImage: typeof import('./src/mocp/components/global-upload-image/global-upload-image.vue')['default']
// 自定义组件
CustomScore: typeof import('./src/mocp/components/widget/custom-score.vue')['default']
CustomState: typeof import('./src/mocp/components/widget/custom-state.vue')['default']
CustomTabbar: typeof import('./src/mocp/components/widget/custom-tabbar.vue')['default']
// uni_modules组件
LsjUpload: typeof import('./src/uni_modules/lsj-upload/components/lsj-upload/lsj-upload.vue')['default']
}
}
......@@ -32,10 +32,26 @@ export const getBasicParamsListApi = (data, config) => {
config
})
}
export const getTerminalListApi = (data, config) => {
export const getAircraftTerminalsApi = (data, config) => {
return http({
method: 'POST',
url: '/terminal/getTerminalList',
url: '/resource/flight/getAircraftTerminals',
data,
config
})
}
export const getAirLinesListApi = (data, config) => {
return http({
method: 'POST',
url: '/resource/getAirlineList',
data,
config
})
}
export const getFlightNumApi = (data, config) => {
return http({
method: 'POST',
url: '/resource/flight/getFlightNum',
data,
config
})
......
import { http } from 'mocp/utils/http'
export const getDecisionApi = (data, config) => {
return http({
method: 'POST',
url: '/workbench/getDecision',
data,
config
})
}
export const updateDecisionApi = (data, config) => {
return http({
method: 'POST',
url: '/workbench/updateDecision',
data,
config
})
}
......@@ -36,7 +36,7 @@ const ps = defineProps({
},
dictkey: {
type: String,
default: 'leaderState'
default: ''
},
modelValue: {
type: String,
......
......@@ -140,7 +140,7 @@ const confirm = (e) => {
//点击清空按钮
const clear = () => {
labelValue.value = ''
defaultValue.value = ''
defaultValue.value = Day().valueOf()
es('update:modelValue', ps.emptyValue)
es('change', ps.emptyValue)
}
......
<template>
<!-- 全局标题+内容样式 -->
<text class="txt" :class="class">
<text class="txt" :class="class" :style="style">
<text class="mocp-color-text-5" :style="getLabelStyle" v-if="label">{{ label }}</text>
<text class="mocp-color-text-4" :style="getValueStyle" v-if="value">{{ value }}</text>
</text>
......@@ -10,6 +10,12 @@
import { computed } from 'vue'
const ps = defineProps({
style: {
type: Object,
default: () => {
return {}
}
},
class: {
type: String,
default: ''
......
......@@ -115,7 +115,7 @@ const queryList = (pageIndex, pageSize) => {
pageIndex,
pageSize
}
if (ps.tabValue) {
if (ps.tabValue != null) {
params[ps.tabValueField] = ps.tabValue
}
if (Object.prototype.toString.call(ps.api) == '[object Function]') {
......
<template>
<!-- 全局下拉框控件 -->
<view class="picker">
<view class="picker" :style="style">
<up-picker
:show="show"
:columns="[getColumns]"
......@@ -15,7 +15,7 @@
:cancelColor="cancelColor"
:confirmColor="confirmColor"
></up-picker>
<view class="picker-content" :class="getPickerClass" @tap="show = true" :style="getStyle">
<view class="picker-content" :class="getPickerClass" @tap="show = true" :style="getContentStyle">
<text class="picker-value">{{ getLabelValue }}</text>
<view class="picker-icon">
<view class="picker-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear">
......@@ -34,6 +34,12 @@ import { cloneDeep } from 'lodash'
const es = defineEmits(['update:modelValue', 'change'])
const ps = defineProps({
style: {
type: Object,
default: () => {
return {}
}
},
//显示为空的value值
emptyValue: {
type: [String, Number],
......@@ -95,7 +101,7 @@ const ps = defineProps({
}
})
//获取下拉框样式
const getStyle = computed(() => {
const getContentStyle = computed(() => {
let pickAlign = 'flex-start'
if (ps.pickAlign == 'center') {
pickAlign = 'center'
......@@ -151,7 +157,7 @@ watch(
labelValue.value = option[ps.labelField]
defaultIndex.value = index
} else {
labelValue.value = ''
labelValue.value = ps.modelValue
defaultIndex.value = 0
}
},
......
<template>
<!-- 全局文件下载 -->
<view class="upload">
<view class="upload" :style="style">
<view class="upload-list">
<view class="upload-item" v-for="(item, index) in getFileList" :key="item.id">
<view class="upload-item-left">
<view class="label">
<template v-if="item.fileType == 'image'">
<template v-if="['image', 'png', 'jpg', 'jpeg', 'gif'].includes(item[typeField].toLowerCase())">
<image src="/static/mocp/image/common/image.png" mode="widthFix" />
</template>
<template v-else-if="item.fileType == 'video'">
<template v-else-if="['video', 'mp4'].includes(item[typeField].toLowerCase())">
<image src="/static/mocp/image/common/video.png" mode="widthFix" />
</template>
<template v-else>
......@@ -57,18 +57,29 @@
</template>
<script setup>
import { computed, ref, watch } from 'vue'
import { computed, nextTick, ref, watch } from 'vue'
import { cloneDeep } from 'lodash'
import { httpInterceptor } from 'mocp/utils/http'
import { onBeforeUnmount } from 'vue'
const es = defineEmits(['update:modelValue', 'change'])
const es = defineEmits(['update:modelValue', 'change', 'getFileList'])
const ps = defineProps({
style: {
type: Object,
default: () => {
return {}
}
},
fileList: {
type: Array,
default: () => {
return []
}
},
typeField: {
type: String,
default: 'fileType'
},
url: {
type: String,
default: '/resource/uploadFile'
......@@ -149,6 +160,7 @@ const onuploadEnd = (e) => {
const res = JSON.parse(e.responseText)
console.log('接口响应结果:', res)
if (res.code == 200) {
res.data[ps.mapFieldName] = res.data.id
fileList.value.push(res.data)
uni.$mocpMessage.showToast(res.message || '上传成功')
} else {
......@@ -171,9 +183,13 @@ watch(
}
es('update:modelValue', files)
es('change', files)
es('getFileList', cloneDeep(value))
},
{ deep: true, immediate: true }
)
onBeforeUnmount(() => {
uni.$emit('$upload-hide', {})
})
</script>
<style lang="scss" scoped>
.upload {
......@@ -203,6 +219,7 @@ watch(
background: #f3f3f3;
box-sizing: border-box;
padding: 0 20rpx 0 24rpx;
border-radius: 4rpx;
.label {
flex: auto;
display: flex;
......
<template>
<view :style="getStyle">{{ value }}</view>
</template>
<script setup>
import { computed } from 'vue'
const ps = defineProps({
// OPEN/CLOSE/跟踪
value: {
type: String,
default: ''
},
size: {
type: [String, Number],
default: 34
}
})
const getStyle = computed(() => {
const _style = {}
if (ps.value == 'OPEN') {
_style.color = '#F53F3F'
}
if (ps.value == 'CLOSE') {
_style.color = '#F53F3F'
}
if (ps.value == '跟踪') {
_style.color = '#00B42A'
}
return {
..._style,
fontSize: ps.size + 'rpx',
display: 'inline-block'
}
})
</script>
<style lang="scss" scoped></style>
export * from './appraisal-record'
export * from './assign-work'
export * from './move-decision'
export const moveDecisionStatus = [
{ label: 'OPEN', value: 1 },
{ label: '跟踪', value: 2 },
{ label: 'CLOSE', value: 3 }
]
export const decisionState = [
{ label: '同意', value: '1' },
{ label: '不同意', value: '0' }
]
......@@ -15,7 +15,7 @@ const useAppraisalRecordStore = defineStore('appraisalRecord', {
},
getters: {
getFileList(state) {
return state.details?.file || []
return JSON.parse(state.details?.file) || []
}
},
actions: {
......@@ -31,7 +31,6 @@ const useAppraisalRecordStore = defineStore('appraisalRecord', {
const res = await getRqmDetailsApi({ id: this.id }, { loading: true })
if (res.code == 200) {
this.details = res.data
this.details.file = JSON.parse(res.data.file)
} else {
uni.$mocpMessage.showToast(res.message)
}
......@@ -41,16 +40,6 @@ const useAppraisalRecordStore = defineStore('appraisalRecord', {
}
},
// 配置持久化
persist: {
// 调整为兼容多端的API
storage: {
setItem(key, value) {
uni.setStorageSync(key, value)
},
getItem(key) {
return uni.getStorageSync(key)
}
}
}
persist: false
})
export default useAppraisalRecordStore
......@@ -101,16 +101,6 @@ const useAssignWorkStore = defineStore('assignWork', {
}
},
// 配置持久化
persist: {
// 调整为兼容多端的API
storage: {
setItem(key, value) {
uni.setStorageSync(key, value)
},
getItem(key) {
return uni.getStorageSync(key)
}
}
}
persist: false
})
export default useAssignWorkStore
import { getAircraftNumbersApi, getBasicParamsListApi, getTerminalListApi } from 'mocp/api/base'
import { getAirLinesListApi, getAircraftNumbersApi, getAircraftTerminalsApi, getBasicParamsListApi, getFlightNumApi } from 'mocp/api/base'
import { defineStore } from 'pinia'
const useBaseStore = defineStore('base', {
state: () => {
return {
selectList: {
deviceNumSelect: [], //机号
terminalSelect: [] //航站下拉数据
deviceNumList: [], //机号
terminalList: [], //航站下拉数据
airlineCodeList: [], //航司下拉数据
flightNumList: [] //航班号下拉数据
},
allBasicParams: {} //系统基础参数
}
},
getters: {
getTerminalSelect(state) {
return state.selectList.terminalSelect?.reduce((q, w) => {
//格式化航站数据
getTerminalObject(state) {
return state.selectList.terminalList?.reduce((q, w) => {
if (!q[w.terminalCode]) {
q[w.terminalCode] = []
}
q[w.terminalCode] = w.terminalCity + '-' + w.terminalName + '-' + w.terminalCode
return q
}, {})
},
getTerminalSelect(state) {
return state.selectList.terminalList?.map((z) => ({
value: z.terminalCode,
label: z.terminalCity + '-' + z.terminalName + '-' + z.terminalCode
}))
},
//格式化航司数据
getAirlineSelect(state) {
return state.selectList.airlineCodeList.map((z) => ({
value: z.zOP3,
zOP2: z.value,
label: z.zOP3 + z.shortName
}))
}
},
actions: {
......@@ -29,7 +46,13 @@ const useBaseStore = defineStore('base', {
mask: true
})
try {
await Promise.all(this.getAircraftNumbers(), this.getBasicParamsList(), this.getTerminalList())
await Promise.all(
this.getAircraftNumbers(),
this.getBasicParamsList(),
this.getAircraftTerminals(),
this.getAirLinesList(),
this.getFlightNum()
)
uni.hideLoading()
} catch (error) {
uni.hideLoading()
......@@ -38,13 +61,35 @@ const useBaseStore = defineStore('base', {
async getAircraftNumbers() {
const res = await getAircraftNumbersApi({})
if (res.code == 200) {
this.selectList.deviceNumSelect = res.data
this.selectList.deviceNumList = res.data
}
},
async getAircraftTerminals() {
const res = await getAircraftTerminalsApi({})
if (res.code == 200) {
this.selectList.terminalList = res.data
}
},
async getAirLinesList() {
const res = await getAirLinesListApi({})
if (res.code == 200) {
this.selectList.airlineCodeList = res.data
.filter((a) => a.sortId !== '0')
.sort((q, w) => Number(q.sortId) - Number(w.sortId))
.map((z) => ({
value: z.zOP2,
label: z.zOP2,
name: z.zCNAME20,
zOP3: z.zOP3,
shortName: z.reduceName,
zCFNAME: z.zCFNAME
}))
}
},
async getTerminalList() {
const res = await getTerminalListApi({ pageSize: 100, pageIndex: 1 })
async getFlightNum() {
const res = await getFlightNumApi({})
if (res.code == 200) {
this.selectList.terminalSelect = res.data.list
this.selectList.flightNumList = res.data
}
},
async getBasicParamsList() {
......
import { defineStore } from 'pinia'
const useMoveDecisionStore = defineStore('moveDecision', {
state: () => {
return {
details: undefined
}
},
getters: {
getFileList(state) {
return state.details?.file ? JSON.parse(state.details?.file) : []
}
},
actions: {
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 useMoveDecisionStore
......@@ -7,7 +7,7 @@ const menuList = ref([
{ id: 4, name: '工作指令', icon: 'gzzl', group: '技术支援', count: 0 },
{ id: 5, name: '技术评估', icon: 'jspg', group: '技术支援', count: 0 },
{ id: 6, name: '运行调查', icon: 'yxdc', group: '维修控制', count: 0 },
{ id: 7, name: '运行决策', icon: 'yxjc', group: '维修控制', count: 0 },
{ id: 7, name: '运行决策', icon: 'yxjc', group: '维修控制', count: 0, url: '/panel/move-decision/list' },
{ id: 8, name: '布置工作', icon: 'bzgz', group: '维修控制', count: 0, url: '/panel/assign-work/list' },
{ id: 9, name: '航站管理', icon: 'hzgl', group: '航站管理', count: 0 },
{ id: 10, name: '协议单位', icon: 'xydw', group: '航站管理', count: 0 },
......
......@@ -3,10 +3,10 @@ import Day from './dayjs'
/**
* 时间戳格式化
* 1715072168340 => 2024-05-07 16:56:08
* 1715072168340 => 2024-05-07 16:56:08 format=YYYY/MM/DD HH:mm:ss
*/
export const timeStampFormat = (timeStamp, opt) => {
if (!timeStamp || timeStamp == -1 || timeStamp == '-1') {
if (!timeStamp || timeStamp == -1 || timeStamp == '-1' || timeStamp == 0 || timeStamp == '0') {
return ''
}
timeStamp = parseInt(String(timeStamp))
......
......@@ -130,6 +130,24 @@
"style": {
"navigationBarTitleText": "tab页面"
}
},
{
"path": "pages/modules/mocp/panel/move-decision/list",
"style": {
"navigationBarTitleText": "运行决策"
}
},
{
"path": "pages/modules/mocp/panel/move-decision/details",
"style": {
"navigationBarTitleText": "查看运行决策"
}
},
{
"path": "pages/modules/mocp/panel/move-decision/edit",
"style": {
"navigationBarTitleText": "编辑运行决策"
}
}
],
"globalStyle": {
......
......@@ -9,10 +9,6 @@
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
.txt {
color: $mocp-danger-6;
font-size: 32rpx;
}
}
&-bottom {
display: flex;
......
......@@ -12,10 +12,6 @@
.desc {
display: flex;
align-items: center;
.type {
color: $mocp-danger-6;
font-size: 34rpx;
}
.txt {
color: $mocp-text-5;
font-size: 34rpx;
......
......@@ -4,7 +4,7 @@
<view class="details">
<view class="details-header">
<view class="details-header-top">
<view class="txt">{{ details.status == 1 ? 'OPEN' : 'ClOSE' }}</view>
<custom-state :value="details.status == 1 ? 'OPEN' : 'CLOSE'" :size="32"></custom-state>
<custom-score
v-if="details.score != -1"
:type="details.eventType == 1 ? 'success' : 'warning'"
......
......@@ -19,13 +19,7 @@
<global-picker pickAlign="right" clearable v-model="formData.appraisee" :options="appraisee" emptyValue="-1"></global-picker>
</up-form-item>
<up-form-item label="机号" :borderBottom="true">
<global-picker
pickAlign="right"
clearable
:options="deviceNumSelect"
v-model="formData.ac"
@change="changeAc"
></global-picker>
<global-picker pickAlign="right" clearable :options="deviceNumList" v-model="formData.ac" @change="changeAc"></global-picker>
</up-form-item>
<up-form-item label="客户" :borderBottom="true">
<up-input border="none" inputAlign="right" clearable v-model="formData.acOwn" disabled disabledColor="#fff"></up-input>
......@@ -142,7 +136,7 @@ const appraisalRecordStore = useAppraisalRecordStore()
const { details, getFileList } = storeToRefs(appraisalRecordStore)
//获取下拉框选项
const {
selectList: { deviceNumSelect }
selectList: { deviceNumList }
} = useBaseStore()
const {
selectList: { appraisee, department, examineType }
......
......@@ -4,7 +4,7 @@
<view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)">
<view class="item-title">
<view class="desc">
<view class="type">{{ item.status == 1 ? 'OPEN' : 'ClOSE' }}</view>
<custom-state :value="item.status == 1 ? 'OPEN' : 'CLOSE'"></custom-state>
<view class="txt">{{ item.appraisee != '-1' ? item.appraisee : '' }}</view>
<view class="place">{{ item.department != '-1' ? item.department : '' }}</view>
</view>
......
......@@ -12,10 +12,6 @@
display: flex;
align-items: center;
justify-content: space-between;
.left {
font-size: 48rpx;
color: $mocp-danger-6;
}
.right {
color: $mocp-text-5;
}
......
......@@ -12,10 +12,6 @@
.left {
display: flex;
align-items: center;
.type {
color: $mocp-danger-6;
font-size: 34rpx;
}
.txt {
color: $mocp-text-5;
font-size: 34rpx;
......
......@@ -13,7 +13,7 @@
<view class="details-header">
<view class="details-header-title">{{ baseStore.getParamNameByValue('LayoutWorkType', details.workType) }}详情</view>
<view class="details-header-top">
<view class="left">{{ details.state == 1 ? 'OPEN' : 'ClOSE' }}</view>
<custom-state :value="details.state == 1 ? 'OPEN' : 'CLOSE'" :size="48"></custom-state>
<view class="right">
<global-field label="提出人:" :value="details.presenter"></global-field>
</view>
......
......@@ -12,7 +12,7 @@
<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.state == 1 ? 'OPEN' : 'ClOSE' }}</view>
<custom-state :value="item.state == 1 ? 'OPEN' : 'CLOSE'"></custom-state>
<view class="txt u-line-1">{{ baseStore.getParamNameByValue('LayoutWorkType', item.workType) }}详情</view>
</view>
<view class="right u-line-1">{{ baseStore.getParamNameByValue('LayoutWorkType', item.workType) }}</view>
......
......@@ -7,7 +7,7 @@
<view class="navbar-box-weather" v-if="weatherInfo">
<!-- <image src="/static/mocp/image/panel/weather.png" /> -->
<view class="info">
<view class="place">{{ baseStore.getTerminalSelect[userStore.userInfo?.terminal] }}</view>
<view class="place">{{ baseStore.getTerminalObject[userStore.userInfo?.terminal] }}</view>
<view class="txt">{{ weatherInfo.weatherInfoTxt }} {{ weatherInfo.temperature }}°</view>
</view>
</view>
......
.details {
background: #fff;
padding: 24rpx;
&-header {
display: flex;
align-items: center;
justify-content: space-between;
}
&-body {
&-box {
padding-bottom: 16rpx;
border-bottom: 2rpx solid #f4f4f4;
}
&-field {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
margin-top: 16rpx;
}
&-item {
margin-top: 16rpx;
.title {
font-size: 34rpx;
color: $mocp-text-5;
margin-bottom: 16rpx;
}
.content {
color: $mocp-text-4;
line-height: 42rpx;
font-size: 30rpx;
}
}
}
&-footer {
&-item {
margin-top: 16rpx;
}
}
}
.time-list {
background: #fff;
margin-top: 16rpx;
padding: 16rpx 24rpx 0 24rpx;
overflow: hidden;
.time-item {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
margin-bottom: 16rpx;
}
}
.item {
padding: 24rpx;
margin-bottom: 16rpx;
border-radius: 12rpx;
background: linear-gradient(#e6eeff, #ffffff, #ffffff);
&-title {
display: flex;
align-items: center;
padding-bottom: 16rpx;
border-bottom: 2rpx solid #f4f4f4;
.left {
display: flex;
align-items: center;
.txt {
color: $mocp-text-5;
font-size: 34rpx;
margin-left: 16rpx;
}
}
}
&-content {
padding-top: 16rpx;
font-size: 30rpx;
color: $mocp-text-4;
line-height: 40rpx;
}
&-footer {
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 @handleRightClick="handleRightClick">
<template v-if="details">
<view class="details">
<view class="details-header">
<view class="details-header-left">
<custom-state :value="useGetDictByValue('moveDecisionStatus', details.state)" :size="48"></custom-state>
</view>
<view class="details-header-right">
<global-icon icon="mind-mapping"></global-icon>
<global-field class="txt" label="编号:" :value="details.decisionNumber" style="margin-left: 8rpx"></global-field>
</view>
</view>
<view class="details-body">
<view class="details-body-box">
<view class="details-body-field">
<global-field label="机号:" :value="details.machineNumber || '-'"></global-field>
<global-field label="机型:" :value="details.model || '-'"></global-field>
</view>
<view class="details-body-field">
<global-field
label="航司:"
:value="useGetDictByValue('', details.aviation, { data: baseStore.getAirlineSelect }) || '-'"
></global-field>
<global-field label="航站:" :value="baseStore.getTerminalObject[details.terminal] || '-'"></global-field>
</view>
<view class="details-body-field">
<global-field label="日期:" :value="timeStampFormat(details.dateTime, { format: 'YYYY/MM/DD HH:mm' })"></global-field>
<global-field label="航班号:" :value="details.flight || '-'"></global-field>
</view>
<view class="details-body-field">
<global-field
label="预计起飞时间:"
:value="timeStampFormat(details.takeOff, { format: 'YYYY/MM/DD HH:mm' }) || '-'"
></global-field>
<global-field
label="运行决策类型:"
:value="baseStore.getParamNameByValue('OperationalDecisionType', details.technicalType) || '-'"
></global-field>
</view>
</view>
<view class="details-body-box">
<view class="details-body-list">
<view class="details-body-item">
<view class="title">故障描述</view>
<view class="content">
{{ details.faultDescription || '暂无内容~' }}
</view>
</view>
<view class="details-body-item">
<view class="title">邮件/电话记录</view>
<view class="content">{{ details.phone || '暂无内容~' }}</view>
</view>
<view class="details-body-item">
<view class="title">附件</view>
<global-upload :fileList="getFileList" :showUpload="false" typeField="fileExt"></global-upload>
</view>
</view>
</view>
<view class="details-footer">
<view class="details-footer-list">
<view class="details-footer-item">
<global-field label="批准人:" :value="details.approver || '-'"></global-field>
</view>
<view class="details-footer-item">
<global-field
label="决策结果:"
:value="useGetDictByValue('decisionState', details.decisionState) || '-'"
></global-field>
</view>
<view class="details-footer-item" v-if="details.decisionState == '0' && details.remark">
<global-field :value="details.remark"></global-field>
</view>
</view>
</view>
</view>
</view>
<view class="time-list">
<view class="time-item">
<global-field label="填报人:" :value="details.filledBy"></global-field>
<global-field label="填报时间:" :value="timeStampFormat(details.filledTime, { format: 'YYYY/MM/DD HH:mm' })"></global-field>
</view>
<view class="time-item">
<global-field label="关闭人:" :value="details.closeBy || '-'"></global-field>
<global-field label="关闭时间:" :value="timeStampFormat(details.closeTime, { format: 'YYYY/MM/DD HH:mm' }) || '-'"></global-field>
</view>
</view>
</template>
</global-page>
</template>
<script setup>
import { useGetDictByValue } from 'mocp/hooks/use-dict/useDict'
import useMoveDecisionStore from 'mocp/store/move-decision'
import useBaseStore from 'mocp/store/base'
import { storeToRefs } from 'pinia'
import { timeStampFormat } from 'mocp/utils/tool'
const baseStore = useBaseStore()
const moveDecisionStore = useMoveDecisionStore()
const { details, getFileList } = storeToRefs(moveDecisionStore)
//跳转
const handleRightClick = () => {
uni.$mocpJump.navigateTo('/panel/move-decision/edit')
}
</script>
<style lang="scss" scoped>
@import './constants/details.scss';
</style>
<template>
<global-page
title="编辑运行决策"
navLeftType="text"
:showNavRight="true"
navRightType="button"
navRightText="保存"
@handleRightClick="handleSave"
>
<view class="mocp-form">
<up-form labelPosition="left" labelWidth="auto" :model="formData">
<up-form-item label="状态" :borderBottom="true">
<global-picker pickAlign="right" v-model="formData.state" clearable dictkey="moveDecisionStatus"></global-picker>
</up-form-item>
<up-form-item label="机号" :borderBottom="true">
<global-picker
pickAlign="right"
v-model="formData.machineNumber"
:options="deviceNumList"
clearable
@change="changeAc"
></global-picker>
</up-form-item>
<up-form-item label="机型" :borderBottom="true">
<up-input border="none" inputAlign="right" clearable v-model="formData.model" disabled disabledColor="#fff"></up-input>
</up-form-item>
<up-form-item label="航司" :borderBottom="true">
<up-input border="none" inputAlign="right" clearable disabled disabledColor="#fff">
<template #suffix>
{{ useGetDictByValue('', formData.aviation, { data: baseStore.getAirlineSelect }) }}
</template>
</up-input>
</up-form-item>
<up-form-item label="航站" :borderBottom="true">
<global-picker pickAlign="right" v-model="formData.terminal" clearable :options="baseStore.getTerminalSelect"></global-picker>
</up-form-item>
<up-form-item label="日期" :borderBottom="true">
<global-date
pickAlign="right"
v-model="formData.dateTime"
clearable
mode="datetime"
format="YYYY/MM/DD HH:mm"
placeholder="请选择日期"
></global-date>
</up-form-item>
<up-form-item label="航班号" :borderBottom="true">
<global-picker
pickAlign="right"
v-model="formData.flight"
clearable
:options="baseStore.selectList.flightNumList"
></global-picker>
</up-form-item>
<up-form-item label="预计起飞时间" :borderBottom="true">
<global-date
pickAlign="right"
v-model="formData.takeOff"
clearable
mode="datetime"
format="YYYY/MM/DD HH:mm"
placeholder="请选择日期"
></global-date>
</up-form-item>
<up-form-item label="运行决策类型" :borderBottom="true">
<global-picker
pickAlign="right"
v-model="formData.technicalType"
clearable
:options="baseStore.getParamsByType('OperationalDecisionType')"
></global-picker>
</up-form-item>
<up-form-item label="故障描述" :borderBottom="true" labelPosition="top">
<up-textarea
v-model.trim="formData.faultDescription"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<up-form-item label="邮件/电话记录" :borderBottom="true" labelPosition="top">
<up-textarea
v-model.trim="formData.phone"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
<up-form-item label="附件" :borderBottom="true" labelPosition="top">
<global-upload
:fileList="getFileList"
typeField="fileExt"
v-model="formData.file"
mapFieldName="ids"
@getFileList="getFileDataList"
style="margin-top: 24rpx"
></global-upload>
</up-form-item>
<up-form-item label="批准人" :borderBottom="true">
<up-input
v-model="formData.approver"
border="none"
inputAlign="right"
placeholder="请输入"
:adjustPosition="false"
clearable
></up-input>
</up-form-item>
<up-form-item label="决策结果" :borderBottom="true">
<global-picker
pickAlign="right"
v-model="formData.decisionState"
clearable
style="margin-top: 24rpx"
dictkey="decisionState"
></global-picker>
</up-form-item>
<up-form-item label="详情" :borderBottom="true" labelPosition="top" v-if="formData.decisionState == '0'">
<up-textarea
v-model.trim="formData.remark"
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="40"
border="none"
></up-textarea>
</up-form-item>
</up-form>
</view>
</global-page>
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
import { reactive, ref } from 'vue'
import useMoveDecisionStore from 'mocp/store/move-decision'
import { storeToRefs } from 'pinia'
import useBaseStore from 'mocp/store/base'
import { useGetDictByValue } from 'mocp/hooks/use-dict/useDict'
import { getAcReduceListApi } from 'mocp/api/base'
import { updateDecisionApi } from 'mocp/api/move-decision'
const baseStore = useBaseStore()
//获取下拉框选项
const {
selectList: { deviceNumList }
} = useBaseStore()
const moveDecisionStore = useMoveDecisionStore()
const { details, getFileList } = storeToRefs(moveDecisionStore)
const formData = reactive({
approver: '',
aviation: '',
dateTime: '',
faultDescription: '',
file: '',
flight: '',
id: '',
machineNumber: '',
model: '',
phone: '',
state: '',
takeOff: '',
technicalType: '',
terminal: '',
decisionState: '',
remark: ''
})
//页面初始化
onLoad(() => {
formData.approver = details.value.approver
formData.aviation = details.value.aviation
formData.dateTime = details.value.dateTime
formData.faultDescription = details.value.faultDescription
formData.flight = details.value.flight
formData.id = details.value.id
formData.machineNumber = details.value.machineNumber
formData.model = details.value.model
formData.phone = details.value.phone
formData.state = details.value.state
formData.takeOff = details.value.takeOff
formData.technicalType = details.value.technicalType
formData.terminal = details.value.terminal
formData.decisionState = details.value.decisionState || ''
formData.remark = details.value.remark
})
//切换机号
const changeAc = async () => {
const res = await getAcReduceListApi({ ac: formData.machineNumber }, { loading: true })
if (res.code == 200) {
formData.model = res.data[0]?.zstortgc
formData.aviation = res.data[0]?.zop3
} else {
uni.$mocpMessage.showToast(res.message)
}
}
//获取文件列表
const fileList = ref([])
const getFileDataList = (data) => {
fileList.value = data
}
//保存
const handleSave = async () => {
const res = await updateDecisionApi(formData, { loading: true })
if (res.code == 200) {
uni.$mocpJump.navigateBack()
uni.$mocpMessage.showToast(res.message)
//更新详情
res.data.file = JSON.stringify(fileList.value)
moveDecisionStore.setState('details', res.data)
} else {
uni.$mocpMessage.showToast(res.message)
}
}
</script>
<style lang="scss" scoped>
.mocp-form {
background: #fff;
margin-bottom: 24rpx;
padding: 0 32rpx;
}
</style>
<template>
<global-page-swiper
title="运行决策"
refresherEnabled
loadingMoreEnabled
:tabList="tabList"
:api="getDecisionApi"
: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">
<custom-state :value="useGetDictByValue('moveDecisionStatus', item.state)"></custom-state>
<text class="txt u-line-1">{{ item.decisionNumber }}</text>
</view>
</view>
<view class="item-content u-line-3">
{{ item.faultDescription || '暂无内容~' }}
</view>
<view class="item-footer">
<view class="label">
<global-icon icon="calendar"></global-icon>
<text class="txt">
{{ timeStampFormat(item.filledTime, { format: 'YYYY/MM/DD HH:mm' }) }}
</text>
</view>
<view class="label">
<global-icon icon="idcard"></global-icon>
<text class="txt">{{ item.filledBy }}</text>
</view>
</view>
</view>
</template>
</global-page-swiper>
</template>
<script setup>
import { ref } from 'vue'
import { timeStampFormat } from 'mocp/utils/tool'
import { getDecisionApi } from 'mocp/api/move-decision'
import { useGetDictByValue } from 'mocp/hooks/use-dict/useDict'
import useMoveDecisionStore from 'mocp/store/move-decision'
const tabList = ref([
{ name: 'OPEN', value: 1 },
{ name: 'CLOSE', value: 3 },
{ name: '跟踪', value: 2 },
{ name: '全部', value: null }
])
//跳转
const moveDecisionStore = useMoveDecisionStore()
const goDetails = (data) => {
uni.$mocpJump.navigateTo('/panel/move-decision/details', { id: data.id }).then(() => {
moveDecisionStore.setState('details', data)
})
}
</script>
<style lang="scss" scoped>
@import './constants/list.scss';
</style>
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