Commit 14cd29be by pangchong

feat: 提交

parent caf23611
......@@ -24,3 +24,19 @@ export const updateRqmDataApi = (data, config) => {
config
})
}
export const getRqmDetailsApi = (data, config) => {
return http({
method: 'POST',
url: '/RepairControl/getRqmDetails',
data,
config
})
}
export const saveRqmOpinionApi = (data, config) => {
return http({
method: 'POST',
url: '/RepairControl/saveRqmOpinion',
data,
config
})
}
......@@ -8,3 +8,19 @@ export const getAircraftNumbersApi = (data, config) => {
config
})
}
export const getAcReduceListApi = (data, config) => {
return http({
method: 'POST',
url: '/system/Aircraft/getAcReduceList',
data,
config
})
}
export const getAdminListApi = (data, config) => {
return http({
method: 'POST',
url: '/system/getAdminList',
data,
config
})
}
......@@ -10,7 +10,7 @@
<view class="picker" :class="{ placeholder: !!getVal, disabled }" :style="getStyle">
<text class="picker-value">{{ getVal }}</text>
<view class="picker-icon">
<view class="picker-icon-close" v-if="clearable && selectedValue" @tap.stop="clear">
<view class="picker-icon-close" v-if="clearable && selectedValue && !disabled" @tap.stop="clear">
<up-icon name="close-circle-fill" color="#c0c4cc" size="36rpx"></up-icon>
</view>
<up-icon name="arrow-right" color="#86909C" size="36rpx"></up-icon>
......@@ -20,7 +20,7 @@
</template>
<script setup>
import { computed, onMounted, ref, watch } from 'vue'
import { computed, ref, watch } from 'vue'
import * as dictData from './dictData'
import { cloneDeep } from 'lodash'
import Day from '@/utils/dayjs'
......@@ -84,7 +84,16 @@ const selectedValue = ref('')
watch(
() => ps.modelValue,
(value) => {
selectedValue.value = value
if (ps.mode == 'selector') {
const option = getOptions.value.find((option) => String(option[ps.valueField]) === String(ps.modelValue))
if (option) {
selectedValue.value = option[ps.labelField]
} else {
selectedValue.value = ''
}
} else {
selectedValue.value = value
}
}
)
//获取options
......@@ -92,7 +101,7 @@ const getOptions = computed(() => {
if (ps.dictkey) {
return cloneDeep(dictData[ps.dictkey])
} else {
if (ps.options && Object.prototype.toString.call(ps.options[0]) == '[object object]') {
if (ps.options && Object.prototype.toString.call(ps.options[0]) == '[object Object]') {
return ps.options
} else {
return ps.options.map((item) => {
......@@ -114,9 +123,9 @@ const onChange = (event) => {
es('update:modelValue', getOptions.value[index][ps.valueField])
es('change', getOptions.value[index][ps.valueField])
} else {
selectedValue.value = event.detail.value
es('update:modelValue', Day(selectedValue.value).valueOf())
es('change', Day(selectedValue.value).valueOf())
selectedValue.value = String(Day(event.detail.value).valueOf())
es('update:modelValue', selectedValue.value)
es('change', selectedValue.value)
}
}
const getVal = computed(() => {
......@@ -127,13 +136,6 @@ const getVal = computed(() => {
return uni.$tool.timeStampFormat(selectedValue.value, { format: 'YYYY-MM-DD' }) || ps.placeholder
}
})
//获取初始值
const init = () => {
const option = getOptions.value.find((option) => String(option[ps.valueField]) === String(ps.modelValue))
if (option) {
selectedValue.value = option[ps.labelField]
}
}
const getPickerValue = computed(() => {
const index = getOptions.value.findIndex((option) => String(option[ps.valueField]) === String(ps.modelValue))
return index > 0 ? index : 0
......@@ -141,10 +143,9 @@ const getPickerValue = computed(() => {
//清空值
const clear = () => {
selectedValue.value = ''
es('update:modelValue', '')
es('change', '')
}
onMounted(() => {
init()
})
</script>
<style lang="scss" scoped>
.picker {
......
<template>
<up-upload
:width="width"
:height="height"
:fileList="fileList"
:width="width + 'rpx'"
:height="height + 'rpx'"
:fileList="getFileList"
@afterRead="afterRead"
@delete="deletePic"
multiple
......@@ -18,21 +18,22 @@
</template>
<script setup>
import { func } from 'uview-plus/libs/function/test'
import { computed, ref, watch } from 'vue'
const es = defineEmits(['update:modelValue', 'change'])
const es = defineEmits(['handleUpload'])
const ps = defineProps({
modelValue: {
fileList: {
type: Array,
default: () => []
},
width: {
type: [String, Number],
default: 80
default: '155'
},
height: {
type: [String, Number],
default: 80
default: '155'
},
url: {
type: String,
......@@ -41,12 +42,23 @@ const ps = defineProps({
})
const getUploadButtonSize = computed(() => {
return {
width: ps.width + 'px',
height: ps.height + 'px'
width: ps.width + 'rpx',
height: ps.height + 'rpx'
}
})
const fileList = ref([])
watch(
() => ps.fileList,
(value) => {
fileList.value = value
}
)
const getFileList = computed(() => {
return fileList.value.map((item) => {
return { ...item, url: item.fileUrl }
})
})
// 删除图片
const deletePic = (event) => {
fileList.value.splice(event.index, 1)
......@@ -64,38 +76,53 @@ const afterRead = async (event) => {
})
})
for (let i = 0; i < lists.length; i++) {
const result = await uploadFilePromise(lists[i].url)
let item = fileList.value[fileListLen]
fileList.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
url: result
})
fileListLen++
const arrayBuffer = new Uint8Array(lists[i].url) //先将本地图片路径转换成array类型
const binary = arrayBufferToBinary(arrayBuffer)
// const binary = uni.getFileSystemManager().readFileSync(lists[i].url, 'binary')
// const imgBlob = await fetch(lists[i].url).then((r) => r.blob())
// const imgFile = new File([imgBlob], lists[i].name, { type: imgBlob.type })
// let form = new FormData()
// form.append('file', imgFile)
const res = await uploadFilePromise(lists[i].url, binary)
if (res.code == 200) {
fileList.value.splice(fileListLen, 1, {
...res.data
})
fileListLen++
} else {
uni.$message.showToast(res.message || '请求错误')
}
}
}
const uploadFilePromise = (url) => {
function arrayBufferToBinary(buffer) {
// 创建一个二进制编码器
const encoder = new TextEncoder()
// 将ArrayBuffer视为UTF-8字符串的字节序列
const view = new Uint8Array(buffer)
// 使用二进制编码器将字节序列转换为字符串
return encoder.encode(new Uint8Array(buffer)).toString()
}
watch(fileList, (value) => {
es('handleUpload', value)
})
const uploadFilePromise = (url, binary) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: ps.url,
filePath: url,
name: 'file',
filePath: url,
file: binary,
formData: {
file: binary
},
success: (res) => {
setTimeout(() => {
resolve(res.data.data)
}, 1000)
resolve(JSON.parse(res.data))
}
})
})
}
watch(
fileList,
(val) => {
es('update:modelValue', val)
},
{ deep: true, immediate: true }
)
</script>
<style lang="scss" scoped>
.upload-button {
......
......@@ -2,7 +2,7 @@
<view class="score" :class="type">
<text class="tag">{{ getTag }}</text>
<text class="count">
<slot></slot>
<slot>{{ count }}</slot>
</text>
</view>
</template>
......@@ -15,6 +15,10 @@ const ps = defineProps({
type: {
type: String,
default: 'success'
},
count: {
type: [String, Number],
default: -1
}
})
const getTag = computed(() => {
......
{
"name" : "",
"appid" : "",
"name" : "mocp-uniapp",
"appid" : "__UNI__A5D387F",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
......@@ -39,7 +39,7 @@
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"versionCode":1001
"versionCode" : 1001
},
/* ios打包配置 */
"ios" : {},
......@@ -66,8 +66,8 @@
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics": {
"enable": false
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}
......@@ -2,14 +2,22 @@
<global-page title="添加公司值班信息" showEdit @handleCancel="handleCancel" @handleSave="handleSave">
<view class="form">
<up-form labelPosition="left" labelWidth="auto">
<up-form-item label="公司值班经理" :borderBottom="true">
<global-picker pickAlign="right" clearable></global-picker>
<up-form-item :label="formData.isDuty == 0 ? '公司值班经理' : '品质中心经理'" :borderBottom="true">
<global-picker pickAlign="right" clearable v-model="formData.mid" :options="selectList"></global-picker>
</up-form-item>
<up-form-item label="公司值班经理意见" :borderBottom="true">
<global-picker pickAlign="right" clearable></global-picker>
<up-form-item :label="formData.isDuty == 0 ? '公司值班经理意见' : '品质中心经理意见'" :borderBottom="true">
<global-picker pickAlign="right" clearable v-model="formData.opinionType" dictkey="opinionType"></global-picker>
</up-form-item>
<up-form-item label="公司值班经理意见描述" :borderBottom="true" labelPosition="top">
<up-textarea placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容" autoHeight></up-textarea>
<up-form-item
:label="formData.isDuty == 0 ? '公司值班经理意见描述' : '品质中心经理意见描述'"
:borderBottom="true"
labelPosition="top"
>
<up-textarea
placeholder="一段很长很长的内容文字,长文本自动换行,该选项的描述是一段很长的内容"
:height="70"
v-model="formData.msg"
></up-textarea>
</up-form-item>
</up-form>
</view>
......@@ -17,13 +25,57 @@
</template>
<script setup>
import { ref } from 'vue'
import { saveRqmOpinionApi } from '@/api/appraisal-record'
import { getAdminListApi } from '@/api/base'
import { onLoad } from '@dcloudio/uni-app'
import { reactive, ref } from 'vue'
//表单数据
const formData = reactive({
id: '',
isDuty: 0,
mid: '-1',
opinionType: -1,
msg: ''
})
onLoad(() => {
uni.$once('appraisalRecordAdd', (data, realName) => {
Object.assign(formData, data)
getAdminList(realName || '')
})
})
//获取下拉框列表
const selectList = ref([])
const getAdminList = async (realName) => {
const params = {
pageIndex: 1,
pageSize: 100,
realName
}
const res = await getAdminListApi(params)
if (res.code == 200) {
selectList.value = res.data.list.map((item) => {
return {
label: `${item.nickname}(${(item.enetAccount || '无易网号') + '-' + (item.deptFullName || '无机构')})`,
value: item.id
}
})
} else {
uni.$message.showToast(res.message)
}
}
const handleCancel = () => {
uni.navigateBack()
}
const handleSave = () => {
console.log('点击保存')
const handleSave = async () => {
const res = await saveRqmOpinionApi(formData, { loading: true })
if (res.code == 200) {
uni.navigateBack()
uni.$message.showToast(res.message)
} else {
uni.$message.showToast(res.message)
}
}
</script>
......
......@@ -15,9 +15,11 @@
<view class="details-header">
<view class="details-header-top">
<view class="txt">{{ details.status == 1 ? 'OPEN' : 'ClOSE' }}</view>
<score-details v-if="details.score > 0" :type="details.eventType == 1 ? 'success' : 'warning'">
{{ details.score }}
</score-details>
<score-details
v-if="details.score != -1"
:type="details.eventType == 1 ? 'success' : 'warning'"
:count="details.score"
></score-details>
</view>
<view class="details-header-bottom">
<view class="left">
......@@ -45,7 +47,7 @@
<view class="details-footer">
<view class="details-footer-top">
<global-icon icon="subscribed" color="#1D2129"></global-icon>
<text>{{ details.examineType }}</text>
<text>{{ showData(details.examineType, '暂无内容~') }}</text>
</view>
<view class="details-footer-center">{{ details.examineBasis }}</view>
<view class="details-footer-bottom">
......@@ -86,20 +88,29 @@
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
import { onShow } from '@dcloudio/uni-app'
import CardDetails from './components/card-details.vue'
import CardDetailsItem from './components/card-details-item.vue'
import { ref } from 'vue'
import { showData, timeStampFormat } from '@/utils/tool'
import { useGetDictByValue } from '@/components/global-picker/useDict'
import { getRqmDetailsApi } from '@/api/appraisal-record'
const details = ref()
const file = ref([])
onLoad(() => {
uni.$once('appraisalRecordDetials', (data) => {
details.value = data
file.value = JSON.parse(details.value.file)
})
//获取详情
const getRqmDetails = async (id) => {
const res = await getRqmDetailsApi({ id }, { loading: true })
if (res.code == 200) {
details.value = res.data
file.value = JSON.parse(res.data.file)
} else {
uni.$message.showToast(res.message)
}
}
const query = defineProps(['id'])
onShow(() => {
getRqmDetails(query.id)
})
//跳转
const goTo = () => {
......
......@@ -13,13 +13,19 @@
<global-picker pickAlign="right" clearable v-model="formData.appraisee" :options="appraisee"></global-picker>
</up-form-item>
<up-form-item label="机号" :borderBottom="true">
<global-picker pickAlign="right" clearable :options="deviceNumSelect" v-model="formData.ac"></global-picker>
<global-picker
pickAlign="right"
clearable
:options="deviceNumSelect"
v-model="formData.ac"
@change="changeAc"
></global-picker>
</up-form-item>
<up-form-item label="客户" :borderBottom="true">
<global-picker pickAlign="right" clearable v-model="formData.acOwn" disabled></global-picker>
<up-input border="none" inputAlign="right" clearable v-model="formData.acOwn" disabled disabledColor="#fff"></up-input>
</up-form-item>
<up-form-item label="机型" :borderBottom="true">
<global-picker pickAlign="right" clearable v-model="formData.acType" disabled></global-picker>
<up-input border="none" inputAlign="right" clearable v-model="formData.acType" disabled disabledColor="#fff"></up-input>
</up-form-item>
<up-form-item label="日期" :borderBottom="true" required prop="eventTime">
<global-picker pickAlign="right" clearable v-model="formData.eventTime" mode="date"></global-picker>
......@@ -56,42 +62,40 @@
type="company"
title="公司值班信息"
showfooter
:idcard="details.dmName"
:calendar="details.optionSaveTime"
v-if="details"
:idcard="formData.dmName"
:calendar="formData.optionSaveTime"
edit
@handleAdd="handleAdd"
@handleAdd="handleAdd(0)"
>
<card-details-item label="公司值班经理">{{ showData(details.dmName, '-') }}</card-details-item>
<card-details-item label="公司值班经理">{{ showData(formData.dmName, '-') }}</card-details-item>
<card-details-item label="公司值班经理意见">
{{ showData(details.opinionType) ? useGetDictByValue('opinionType', details.opinionType) : '-' }}
{{ showData(formData.opinionType) ? useGetDictByValue('opinionType', formData.opinionType) : '-' }}
</card-details-item>
<card-details-item label="公司值班经理意见描述">{{ showData(details.dmMsg, '-') }}</card-details-item>
<card-details-item label="公司值班经理意见描述">{{ showData(formData.dmMsg, '-') }}</card-details-item>
</card-details>
<card-details
type="quality"
title="品质中心信息"
showfooter
:idcard="details.qmName"
:calendar="details.qualitySaveTime"
v-if="details"
:idcard="formData.qmName"
:calendar="formData.qualitySaveTime"
edit
@handleAdd="handleAdd"
@handleAdd="handleAdd(1)"
>
<card-details-item label="品质中心经理">{{ showData(details.qmName, '-') }}</card-details-item>
<card-details-item label="品质中心经理">{{ showData(formData.qmName, '-') }}</card-details-item>
<card-details-item label="品质中心经理意见">
{{ showData(details.qualityOpinionType) ? useGetDictByValue('opinionType', details.qualityOpinionType) : '-' }}
{{ showData(formData.qualityOpinionType) ? useGetDictByValue('opinionType', formData.qualityOpinionType) : '-' }}
</card-details-item>
<card-details-item label="品质中心经理意见描述">{{ showData(details.qmMsg, '-') }}</card-details-item>
<card-details-item label="品质中心经理意见描述">{{ showData(formData.qmMsg, '-') }}</card-details-item>
</card-details>
<view class="appeal">
<view class="appeal-title">
<text>申诉情况</text>
<global-picker pickAlign="right" dictkey="appealInfo" clearable></global-picker>
<global-picker pickAlign="right" dictkey="appealInfo" v-model="formData.appealInfo" clearable></global-picker>
</view>
<view class="appeal-content">
<global-upload :fileList="formData.file" url="/resource/uploadFile" @handleUpload="handleUpload"></global-upload>
</view>
<!-- <view class="appeal-content">
<global-upload v-model="formData.file" url="/resource/uploadFile"></global-upload>
</view> -->
</view>
</view>
<template #bottom>
......@@ -112,9 +116,10 @@ import useBaseStore from '@/store/base'
import { useGetDictByValue } from '@/components/global-picker/useDict'
import useAppraisalRecordStore from '@/store/appraisal-record'
import { updateRqmDataApi } from '@/api/appraisal-record'
import { getAcReduceListApi } from '@/api/base'
// 校验规则
const rules = {
const rules = reactive({
eventTime: [
{
required: true,
......@@ -122,7 +127,7 @@ const rules = {
trigger: ['blur', 'change']
}
]
}
})
//获取下拉框选项
const {
selectList: { deviceNumSelect }
......@@ -136,49 +141,84 @@ const formData = reactive({
ac: '',
acOwn: '',
acType: '',
appealInfo: '',
appraisee: '',
department: '',
dmUid: '',
appealInfo: '-1',
appraisee: '-1',
department: '-1',
dmUid: '-1',
eventMsg: '',
eventSource: '',
eventTime: '',
eventType: '',
eventTime: -1,
eventType: -1,
examineBasis: '',
examineType: '',
examineType: '-1',
onDutyUser: '',
opinionMsg: '',
opinionType: '',
opinionType: -1,
score: null,
qmUid: '',
qualityOpinionMsg: '',
qualityOpinionType: '',
qualityOpinionType: -1,
status: '',
file: [],
emailSendTime: ''
emailSendTime: -1
})
//提交表单
const formRef = ref()
const handleSubmit = async () => {
await formRef.value?.validate()
const res = await updateRqmDataApi(formData, { loading: true })
const params = { ...formData, file: JSON.stringify(file.value) }
const res = await updateRqmDataApi(params, { loading: true })
if (res.code == 200) {
uni.navigateBack()
uni.$message.showToast(res.message)
} else {
uni.$message.showToast(res.message)
}
}
// 添加
const handleAdd = () => {
uni.navigateTo({ url: 'add' })
const handleAdd = (isDuty) => {
let params = {}
let realName = ''
if (isDuty == 0) {
params = { id: details.value.id, isDuty, mid: details.value.dmUid, opinionType: details.value.opinionType, msg: details.value.dmMsg }
realName = details.value.dmName
} else {
params = { id: details.value.id, isDuty, mid: details.value.qmUid, opinionType: details.value.qualityOpinionType, msg: details.value.qmMsg }
realName = details.value.qmName
}
uni.navigateTo({
url: 'add',
success: () => {
uni.$emit('appraisalRecordAdd', params, realName)
}
})
}
//获取页面内容
const file = ref([])
const details = ref()
onLoad(() => {
uni.$once('appraisalRecordEdit', (data) => {
details.value = data
Object.assign(formData, data)
formData.file = JSON.parse(data.file)
file.value = JSON.parse(data.file)
formData.eventTime = String(data.eventTime)
})
})
//获取文件内容
const handleUpload = (fileList) => {
file.value = fileList
}
//切换机号
const changeAc = async () => {
const res = await getAcReduceListApi({ ac: formData.ac }, { loading: true })
if (res.code == 200) {
formData.acOwn = res.data[0]?.zop3
formData.acType = res.data[0]?.zstortgc
} else {
uni.$message.showToast(res.message)
}
}
</script>
<style lang="scss" scoped>
.content {
......
......@@ -9,7 +9,11 @@
<view class="txt">{{ showData(item.appraisee) }}</view>
<view class="place">{{ showData(item.department) }}</view>
</view>
<score-details v-if="item.score > 0" :type="item.eventType == 1 ? 'success' : 'warning'">{{ item.score }}</score-details>
<score-details
v-if="item.score != -1"
:type="item.eventType == 1 ? 'success' : 'warning'"
:count="item.score"
></score-details>
</view>
<view class="item-content">
{{ item.eventMsg || '暂无内容~' }}
......@@ -35,10 +39,7 @@ const tabList = ref([
//跳转
const goDetails = (data) => {
uni.navigateTo({
url: 'details',
success: () => {
uni.$emit('appraisalRecordDetials', data)
}
url: 'details?id=' + data.id
})
}
//加载下拉框数据
......
......@@ -79,7 +79,6 @@ const httpInterceptor = {
uid: userStore.userInfo?.id
}
options.header = {
'Content-Type': 'multipart/form-data',
...options.header
}
} else {
......@@ -92,6 +91,7 @@ const httpInterceptor = {
if (userStore.token) {
options.header.Authorization = `Bearer ${userStore.token}`
}
console.log('接口请求信息:', options)
}
}
uni.addInterceptor('request', httpInterceptor)
......@@ -119,17 +119,18 @@ export const http = (options) => {
success(res) {
serviceLoading.close()
// 状态码 2xx, axios 就是这样设计的
if (res.statusCode >= 200 && res.statusCode < 300) {
const statusCode = parseInt(res.statusCode)
if (statusCode >= 200 && statusCode < 300) {
// 2.1 提取核心数据 res.data
resolve(res.data)
} else if (res.statusCode === 401) {
} else if (statusCode === 401) {
// 401错误 -> 清理用户信息,跳转到登录页
const userStore = useUserStore()
userStore.handleLogOut()
reject(res)
} else {
// 其他错误 -> 根据后端错误信息轻提示
uni.$message.showToast(res.data.msg || '请求错误')
uni.$message.showToast(res.data.message || '请求错误')
reject(res)
}
},
......
......@@ -29,7 +29,7 @@ export const showData = (data, result = '') => {
* 1715072168340 => 2024-05-07 16:56:08
*/
export const timeStampFormat = (timeStamp, opt) => {
if (!timeStamp) {
if (!timeStamp || timeStamp == -1 || timeStamp == '-1') {
return ''
}
timeStamp = parseInt(String(timeStamp))
......
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