Commit 0561260c by pangchong

feat: 调整

parent 08b7c520
{
"compilerOptions": {
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"lib": ["esnext", "dom"],
"types": [
"@dcloudio/types",
"@uni-helper/uni-app-types",
"@uni-helper/uni-ui-types"
]
}
}
\ No newline at end of file
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
"@dcloudio/uni-cli-shared": "3.0.0-4010520240507001", "@dcloudio/uni-cli-shared": "3.0.0-4010520240507001",
"@dcloudio/uni-stacktracey": "3.0.0-4010520240507001", "@dcloudio/uni-stacktracey": "3.0.0-4010520240507001",
"@dcloudio/vite-plugin-uni": "3.0.0-4010520240507001", "@dcloudio/vite-plugin-uni": "3.0.0-4010520240507001",
"@uni-helper/uni-app-types": "^0.5.13",
"@uni-helper/uni-ui-types": "^0.5.14",
"@vue/runtime-core": "^3.4.21", "@vue/runtime-core": "^3.4.21",
"sass": "^1.77.1", "sass": "^1.77.1",
"sass-loader": "^14.2.1", "sass-loader": "^14.2.1",
...@@ -4305,6 +4307,45 @@ ...@@ -4305,6 +4307,45 @@
"dev": true, "dev": true,
"peer": true "peer": true
}, },
"node_modules/@uni-helper/uni-app-types": {
"version": "0.5.13",
"resolved": "https://registry.npmmirror.com/@uni-helper/uni-app-types/-/uni-app-types-0.5.13.tgz",
"integrity": "sha512-NIKHv9Zof7sxsznjH+LRB2VM8ncEyfpkwRVLm7u2N1X3e1RFWvABH+bttfu+d8FIP6JzksBNOQwsyZjDnLN0fw==",
"dev": true,
"dependencies": {
"@dcloudio/types": "^3.4.8",
"vue3": "npm:vue@^3.4.26"
},
"engines": {
"node": ">=14.18"
},
"peerDependencies": {
"typescript": "^4.8.0 || ^5.0.0"
}
},
"node_modules/@uni-helper/uni-ui-types": {
"version": "0.5.14",
"resolved": "https://registry.npmmirror.com/@uni-helper/uni-ui-types/-/uni-ui-types-0.5.14.tgz",
"integrity": "sha512-bU0lE0iU4PHczzcAMW5L8LbmPWf1kAlpfDQzYeOq6pcsfgdgcosisSK/9jjrmWlDk02XWyQL9NMhmSjfK9X0CA==",
"dev": true,
"dependencies": {
"@dcloudio/types": "^3.4.8",
"@uni-helper/uni-app-types": "^0.5.13",
"vue3": "npm:vue@^3.4.27"
},
"engines": {
"node": ">=14.18"
},
"peerDependencies": {
"@uni-helper/uni-app-types": "^0.5.13",
"typescript": "^4.8.0 || ^5.0.0"
},
"peerDependenciesMeta": {
"@uni-helper/uni-app-types": {
"optional": true
}
}
},
"node_modules/@vitejs/plugin-legacy": { "node_modules/@vitejs/plugin-legacy": {
"version": "5.4.0", "version": "5.4.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-5.4.0.tgz", "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-5.4.0.tgz",
...@@ -10917,6 +10958,20 @@ ...@@ -10917,6 +10958,20 @@
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"node_modules/typescript": {
"version": "5.4.5",
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz",
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"devOptional": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/ufo": { "node_modules/ufo": {
"version": "1.5.3", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz",
...@@ -11350,6 +11405,130 @@ ...@@ -11350,6 +11405,130 @@
"vue": "^3.2.0" "vue": "^3.2.0"
} }
}, },
"node_modules/vue3": {
"name": "vue",
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.27.tgz",
"integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
"dev": true,
"dependencies": {
"@vue/compiler-dom": "3.4.27",
"@vue/compiler-sfc": "3.4.27",
"@vue/runtime-dom": "3.4.27",
"@vue/server-renderer": "3.4.27",
"@vue/shared": "3.4.27"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vue3/node_modules/@vue/compiler-core": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
"integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.24.4",
"@vue/shared": "3.4.27",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/vue3/node_modules/@vue/compiler-dom": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
"integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
"dev": true,
"dependencies": {
"@vue/compiler-core": "3.4.27",
"@vue/shared": "3.4.27"
}
},
"node_modules/vue3/node_modules/@vue/compiler-sfc": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
"integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.24.4",
"@vue/compiler-core": "3.4.27",
"@vue/compiler-dom": "3.4.27",
"@vue/compiler-ssr": "3.4.27",
"@vue/shared": "3.4.27",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.10",
"postcss": "^8.4.38",
"source-map-js": "^1.2.0"
}
},
"node_modules/vue3/node_modules/@vue/compiler-ssr": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
"integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
"dev": true,
"dependencies": {
"@vue/compiler-dom": "3.4.27",
"@vue/shared": "3.4.27"
}
},
"node_modules/vue3/node_modules/@vue/runtime-dom": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
"integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
"dev": true,
"dependencies": {
"@vue/runtime-core": "3.4.27",
"@vue/shared": "3.4.27",
"csstype": "^3.1.3"
}
},
"node_modules/vue3/node_modules/@vue/server-renderer": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
"integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
"dev": true,
"dependencies": {
"@vue/compiler-ssr": "3.4.27",
"@vue/shared": "3.4.27"
},
"peerDependencies": {
"vue": "3.4.27"
}
},
"node_modules/vue3/node_modules/@vue/shared": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.27.tgz",
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
"dev": true
},
"node_modules/vue3/node_modules/vue": {
"version": "3.4.27",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.27.tgz",
"integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
"dev": true,
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.4.27",
"@vue/compiler-sfc": "3.4.27",
"@vue/runtime-dom": "3.4.27",
"@vue/server-renderer": "3.4.27",
"@vue/shared": "3.4.27"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/w3c-hr-time": { "node_modules/w3c-hr-time": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
......
...@@ -67,6 +67,8 @@ ...@@ -67,6 +67,8 @@
"@dcloudio/uni-cli-shared": "3.0.0-4010520240507001", "@dcloudio/uni-cli-shared": "3.0.0-4010520240507001",
"@dcloudio/uni-stacktracey": "3.0.0-4010520240507001", "@dcloudio/uni-stacktracey": "3.0.0-4010520240507001",
"@dcloudio/vite-plugin-uni": "3.0.0-4010520240507001", "@dcloudio/vite-plugin-uni": "3.0.0-4010520240507001",
"@uni-helper/uni-app-types": "^0.5.13",
"@uni-helper/uni-ui-types": "^0.5.14",
"@vue/runtime-core": "^3.4.21", "@vue/runtime-core": "^3.4.21",
"sass": "^1.77.1", "sass": "^1.77.1",
"sass-loader": "^14.2.1", "sass-loader": "^14.2.1",
......
<script> <script>
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/user'
export default { export default {
onLaunch: function () { onLaunch: function () {
console.log('App Launch') console.log('App Launch')
......
import { http } from '@/utils/http'
export const getRqmListApi = (data, config) => {
return http({
method: 'POST',
url: '/RepairControl/getRqmList',
data,
config
})
}
export const getRqmOptionsApi = (data, config) => {
return http({
method: 'POST',
url: '/RepairControl/getRqmOptions',
data,
config
})
}
\ No newline at end of file
<template>
<view class="uni-form-item" :class="{ labelTop: labelPosition == 'top' }">
<view class="uni-form-item-label" :style="{ width: labelWidth ? labelWidth + 'rpx' : 'auto', color: labelColor }">
<uni-icons v-if="required" class="required-icon" name="required-icon" color="#f00"></uni-icons>
{{ label }}
<text v-if="must" class="must-icon">*</text>
</view>
<view class="uni-form-item-body">
<view class="uni-form-item-content">
<slot></slot>
</view>
<uni-icons v-if="arrow" :name="arrowName" :color="arrowColor" :size="35"></uni-icons>
</view>
</view>
</template>
<script setup>
const ps = defineProps({
labelWidth: {
type: Number,
default: 0
},
label: {
type: String,
default: ''
},
labelPosition: {
type: String,
default: 'left'
},
arrow: {
type: Boolean,
default: false
},
arrowName: {
type: String,
default: 'icon-arrow-right'
},
labelColor: {
type: String,
default: '#1D2129'
},
arrowColor: {
type: String,
default: '#999'
},
required: {
type: Boolean,
default: false
},
must: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
}
})
</script>
<style lang="scss" scoped>
.uni-form-item {
display: flex;
border-bottom: 2rpx solid #f4f4f4;
background: #fff;
padding: 24rpx 32rpx;
font-size: 28rpx;
&.labelTop {
flex-direction: column;
.uni-form-item-content {
margin-top: 8rpx;
}
}
&-label {
font-size: 28rpx;
margin-right: 20rpx;
min-width: 20%;
max-width: 60%;
.required-icon {
width: 28rpx;
}
.must-icon {
color: red;
position: relative;
bottom: -3rpx;
}
}
&-body {
flex: auto;
overflow: hidden;
display: flex;
font-size: 28rpx;
color: #4e5969;
align-items: center;
}
&-content {
flex: auto;
display: flex;
overflow: hidden;
justify-content: flex-end;
font-size: 28rpx;
:deep(textarea) {
height: 80rpx;
width: 100%;
}
:deep(.input-placeholder),
:deep(.uni-input-input),
:deep(input) {
flex: auto;
text-align: right;
font-size: 28rpx;
}
}
}
</style>
<template> <template>
<view class="content"> <view class="content">
<z-paging <z-paging
:auto="auto"
:refresher-enabled="refresherEnabled" :refresher-enabled="refresherEnabled"
:refresher-threshold="refresherThreshold" :refresher-threshold="refresherThreshold"
:auto-show-back-to-top="autoShowBackToTop" :auto-show-back-to-top="autoShowBackToTop"
...@@ -31,7 +32,16 @@ const firstLoaded = ref(false) ...@@ -31,7 +32,16 @@ const firstLoaded = ref(false)
// 是否滚动到当前页 // 是否滚动到当前页
const isCurrentPage = ref(false) const isCurrentPage = ref(false)
const props = defineProps({ const ps = defineProps({
//是否自动加载
auto: {
type: Boolean,
default: false
},
tabValue: {
type: [Number, String],
default: 0
},
tabIndex: { tabIndex: {
type: Number, type: Number,
default: 0 default: 0
...@@ -40,6 +50,16 @@ const props = defineProps({ ...@@ -40,6 +50,16 @@ const props = defineProps({
type: Number, type: Number,
default: 0 default: 0
}, },
//tab数据搜索字段
tabValueField: {
type: String,
default: 'status'
},
//查询接口
api: {
type: Function,
default: null
},
//是否开启下拉刷新 //是否开启下拉刷新
refresherEnabled: { refresherEnabled: {
type: Boolean, type: Boolean,
...@@ -65,9 +85,9 @@ const props = defineProps({ ...@@ -65,9 +85,9 @@ const props = defineProps({
}) })
watch( watch(
() => props.currentIndex, () => ps.currentIndex,
(newVal) => { (newVal) => {
if (newVal === props.tabIndex) { if (newVal === ps.tabIndex) {
// 懒加载,当滑动到当前的item时,才去加载 // 懒加载,当滑动到当前的item时,才去加载
if (!firstLoaded.value) { if (!firstLoaded.value) {
// 这里需要延迟渲染z-paging的原因是为了避免在一些平台上立即渲染可能引发的底层报错问题 // 这里需要延迟渲染z-paging的原因是为了避免在一些平台上立即渲染可能引发的底层报错问题
...@@ -82,14 +102,31 @@ watch( ...@@ -82,14 +102,31 @@ watch(
} }
) )
const queryList = (pageNo, pageSize) => { const queryList = (pageIndex, pageSize) => {
if (!dataList.value.length) { if (!dataList.value.length) {
paging.value?.complete(dataList.value) paging.value?.complete(dataList.value)
} }
setTimeout(() => { const params = {
paging.value?.complete([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) pageIndex,
pageSize,
[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 || [])
firstLoaded.value = true firstLoaded.value = true
}, 500) } else {
uni.$message.showToast(res.message)
}
})
.catch(() => {
paging.value?.complete(false)
})
} else {
paging.value?.complete(false)
}
} }
</script> </script>
......
...@@ -10,15 +10,19 @@ ...@@ -10,15 +10,19 @@
</template> </template>
</global-navbar> </global-navbar>
<!-- tab切换 --> <!-- tab切换 -->
<z-tabs ref="tabs" :list="tabList" :current="current" @change="tabsChange"></z-tabs> <z-tabs ref="tabs" :list="tabList" :current="current" @change="tabsChange" :name-key="nameKey" :value-key="valueKey"></z-tabs>
<slot name="top"></slot> <slot name="top"></slot>
</template> </template>
<!-- 滚动内容 --> <!-- 滚动内容 -->
<swiper class="swiper" :current="current" @transition="swiperTransition" @animationfinish="swiperAnimationfinish"> <swiper class="swiper" :current="current" @transition="swiperTransition" @animationfinish="swiperAnimationfinish">
<swiper-item v-for="(_, index) in tabList" :key="index"> <swiper-item v-for="(_, index) in tabList" :key="index">
<global-page-swiper-item <global-page-swiper-item
:auto="auto"
:tabValue="tabList[current][valueKey]"
:tabIndex="index" :tabIndex="index"
:tabValueField="tabValueField"
:currentIndex="current" :currentIndex="current"
:api="api"
:refresher-enabled="refresherEnabled" :refresher-enabled="refresherEnabled"
:refresher-threshold="refresherThreshold" :refresher-threshold="refresherThreshold"
:auto-show-back-to-top="autoShowBackToTop" :auto-show-back-to-top="autoShowBackToTop"
...@@ -41,6 +45,11 @@ import { ref } from 'vue' ...@@ -41,6 +45,11 @@ import { ref } from 'vue'
const { safeAreaInsets } = uni.getSystemInfoSync() const { safeAreaInsets } = uni.getSystemInfoSync()
const ps = defineProps({ const ps = defineProps({
//是否自动加载
auto: {
type: Boolean,
default: true
},
//tab数据 //tab数据
tabList: { tabList: {
type: Array, type: Array,
...@@ -51,6 +60,21 @@ const ps = defineProps({ ...@@ -51,6 +60,21 @@ const ps = defineProps({
type: Number, type: Number,
default: 0 default: 0
}, },
//tab数据name
nameKey: {
type: String,
default: 'name'
},
//tab数据value
valueKey: {
type: String,
default: 'value'
},
//tab数据搜索字段
tabValueField: {
type: String,
default: 'status'
},
//是否展示自定义导航栏 //是否展示自定义导航栏
showNavbar: { showNavbar: {
type: Boolean, type: Boolean,
...@@ -66,6 +90,11 @@ const ps = defineProps({ ...@@ -66,6 +90,11 @@ const ps = defineProps({
type: Boolean, type: Boolean,
default: true default: true
}, },
//查询接口
api: {
type: Function,
default: null
},
//是否开启下拉刷新 //是否开启下拉刷新
refresherEnabled: { refresherEnabled: {
type: Boolean, type: Boolean,
......
...@@ -21,7 +21,11 @@ ...@@ -21,7 +21,11 @@
<!-- 自定义导航栏 --> <!-- 自定义导航栏 -->
<global-navbar :title="title" v-if="showNavbar"> <global-navbar :title="title" v-if="showNavbar">
<template #left> <template #left>
<uni-icons type="left" size="16" @tap="goBack"></uni-icons> <view v-if="isEdit" class="cancel" @tap="handleCancel">取消</view>
<uni-icons type="left" size="16" @tap="goBack" v-else></uni-icons>
</template>
<template #right>
<global-button type="primary" size="small" v-if="isEdit" style="padding: 0 32rpx" @tap="handleSave">保存</global-button>
</template> </template>
</global-navbar> </global-navbar>
<slot name="top"></slot> <slot name="top"></slot>
...@@ -39,9 +43,10 @@ ...@@ -39,9 +43,10 @@
import { ref } from 'vue' import { ref } from 'vue'
const dataList = ref([]) const dataList = ref([])
const es = defineEmits(['query']) const es = defineEmits(['query', 'handleCancel', 'handleSave'])
const paging = ref() const paging = ref()
const ps = defineProps({ const ps = defineProps({
//是否自动加载
auto: { auto: {
type: Boolean, type: Boolean,
default: false default: false
...@@ -51,6 +56,11 @@ const ps = defineProps({ ...@@ -51,6 +56,11 @@ const ps = defineProps({
type: Boolean, type: Boolean,
default: true default: true
}, },
//页面是否编辑状态
showEdit: {
type: Boolean,
default: false
},
//页面标题 //页面标题
title: { title: {
type: String, type: String,
...@@ -108,9 +118,30 @@ const query = (pageIndex, pageSize) => { ...@@ -108,9 +118,30 @@ const query = (pageIndex, pageSize) => {
complete() complete()
} }
} }
//获取页面状态
const isEdit = ref(ps.showEdit)
//返回 //返回
const goBack = () => { const goBack = () => {
uni.navigateBack() uni.navigateBack()
} }
//取消
const handleCancel = () => {
es('handleCancel')
}
//保存
const handleSave = () => {
es('handleSave')
}
//修改编辑状态
const handleChangeEdit = (value) => {
isEdit.value = value
}
defineExpose({
handleChangeEdit
})
</script> </script>
<style scoped></style> <style scoped>
.cancel {
font-size: 28rpx;
}
</style>
<template>
<view class="upload">
<view class="upload-image">
<image src="/static/image/login/upload.png" />
<view class="upload-del">
<uni-icons type="closeempty" :size="14" color="#fff"></uni-icons>
</view>
</view>
<view class="upload-button" @tap="handleUpload">
<uni-icons type="plusempty" :size="24" color="rgba(0, 0, 0, 0.4)"></uni-icons>
</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
//上传图片
const handleUpload = () => {
// 调用拍照/选择图片
// 选择图片条件编译
// #ifdef H5 || APP-PLUS
// 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替
uni.chooseImage({
count: 1,
success: (res) => {
// 文件路径
const tempFilePaths = res.tempFilePaths
// 上传
uploadFile(tempFilePaths[0])
}
})
// #endif
// #ifdef MP-WEIXIN
// uni.chooseMedia 仅支持微信小程序端
uni.chooseMedia({
// 文件个数
count: 1,
// 文件类型
mediaType: ['image'],
success: (res) => {
// 本地路径
const { tempFilePath } = res.tempFiles[0]
// 上传
uploadFile(tempFilePath)
}
})
// #endif
}
// 文件上传-兼容小程序端、H5端、App端
const uploadFile = (file) => {
// 文件上传
uni.uploadFile({
url: '/member/profile/avatar',
name: 'file',
filePath: file,
success: (res) => {
if (res.statusCode === 200) {
const avatar = JSON.parse(res.data).result.avatar
uni.showToast({ icon: 'success', title: '更新成功' })
} else {
uni.showToast({ icon: 'error', title: '出现错误' })
}
}
})
}
</script>
<style lang="scss" scoped>
.upload {
display: flex;
flex-wrap: wrap;
&-image {
position: relative;
margin-right: 16rpx;
image {
width: 160rpx;
height: 160rpx;
}
}
&-del {
position: absolute;
top: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
width: 32rpx;
height: 32rpx;
display: flex;
align-items: center;
justify-content: center;
}
&-button {
width: 160rpx;
height: 160rpx;
display: flex;
align-items: center;
justify-content: center;
background: #f3f3f3;
}
}
</style>
<template> <template>
<view class="score" :class="type"> <view class="score" :class="type">
<text class="tag">{{ getTag }}</text> <text class="tag">{{ getTag }}</text>
<text class="count">{{ count }}</text> <text class="count">
<slot></slot>
</text>
</view> </view>
</template> </template>
...@@ -13,10 +15,6 @@ const ps = defineProps({ ...@@ -13,10 +15,6 @@ const ps = defineProps({
type: { type: {
type: String, type: String,
default: 'success' default: 'success'
},
count: {
type: Number,
default: 8
} }
}) })
const getTag = computed(() => { const getTag = computed(() => {
...@@ -30,7 +28,6 @@ const getTag = computed(() => { ...@@ -30,7 +28,6 @@ const getTag = computed(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.score { .score {
border-radius: 6rpx; border-radius: 6rpx;
width: 108rpx;
color: #fff; color: #fff;
font-size: 22rpx; font-size: 22rpx;
display: flex; display: flex;
...@@ -40,7 +37,10 @@ const getTag = computed(() => { ...@@ -40,7 +37,10 @@ const getTag = computed(() => {
border-radius: 6rpx; border-radius: 6rpx;
text-align: center; text-align: center;
padding: 2px 0; padding: 2px 0;
margin-right: 16rpx; }
.count {
min-width: 58rpx;
text-align: center;
} }
&.success { &.success {
background: #e8ffea; background: #e8ffea;
......
import { createSSRApp } from 'vue' import { createSSRApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import pinia from './store' import pinia from './store'
import message from '@/utils/message'
// 引入字体 // 引入字体
import '@/static/font/iconfont.css' import '@/static/font/iconfont.css'
//消息提示
uni.$message = message
export function createApp() { export function createApp() {
const app = createSSRApp(App) const app = createSSRApp(App)
app.use(pinia) app.use(pinia)
......
...@@ -52,29 +52,30 @@ ...@@ -52,29 +52,30 @@
} }
}, },
{ {
"path": "pages/panel/assessment-records/list", "path": "pages/panel/appraisal-record/list",
"style": { "style": {
"navigationBarTitleText": "考核记录", "navigationBarTitleText": "考核记录",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{ {
"path": "pages/panel/assessment-records/details", "path": "pages/panel/appraisal-record/details",
"style": { "style": {
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{ {
"path": "pages/panel/assessment-records/edit", "path": "pages/panel/appraisal-record/edit",
"style": { "style": {
"navigationBarTitleText": "考核记录登记", "navigationBarTitleText": "考核记录登记",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{ {
"path": "pages/panel/assessment-records/add", "path": "pages/panel/appraisal-record/add",
"style": { "style": {
"navigationBarTitleText": "添加公司值班信息" "navigationBarTitleText": "添加公司值班信息",
"navigationStyle": "custom"
} }
} }
], ],
...@@ -82,7 +83,10 @@ ...@@ -82,7 +83,10 @@
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app", "navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8", "navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8" "backgroundColor": "#F8F8F8",
"navigationBarRightButton": {
"hide": true
}
}, },
"tabBar": { "tabBar": {
"color": "#1D2129", "color": "#1D2129",
......
...@@ -39,8 +39,7 @@ ...@@ -39,8 +39,7 @@
import { ref, toRaw, watch } from 'vue' import { ref, toRaw, watch } from 'vue'
import { loginApi } from '@/api/user' import { loginApi } from '@/api/user'
import { debounce } from 'lodash' import { debounce } from 'lodash'
import message from '@/utils/message' import useUserStore from '@/store/user'
import useUserStore from '@/store/modules/user'
import { loginCode, loginForm, rules } from './constants/index.compositions' import { loginCode, loginForm, rules } from './constants/index.compositions'
import { getGifCaptcha } from './constants/index.functionals' import { getGifCaptcha } from './constants/index.functionals'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
...@@ -62,7 +61,7 @@ const handleLogin = async () => { ...@@ -62,7 +61,7 @@ const handleLogin = async () => {
if (res.code == 200) { if (res.code == 200) {
userStore.setUserInfo(res.data) userStore.setUserInfo(res.data)
} else { } else {
message.error({ title: res.message }) uni.$message.showToast(res.message)
} }
} }
onLoad(() => { onLoad(() => {
......
...@@ -28,8 +28,5 @@ ...@@ -28,8 +28,5 @@
box-sizing: border-box; box-sizing: border-box;
} }
} }
.menu-empty{
padding: 48rpx 0 32rpx 0;
}
} }
} }
\ No newline at end of file
<template> <template>
<global-page :showNavbar="false"> <global-page ref="pageRef" title="应用中心" @handleCancel="handleCancel" @handleSave="handleSave">
<template #top>
<global-navbar title="应用中心">
<template #left>
<view v-if="isEdit" @tap="isEdit = false" class="cancel">取消</view>
<uni-icons type="left" size="16" @tap="goBack" v-else></uni-icons>
</template>
<template #right>
<global-button type="primary" size="small" v-if="isEdit" style="padding: 0 32rpx">保存</global-button>
</template>
</global-navbar>
</template>
<view class="content"> <view class="content">
<view class="card"> <view class="card">
<view class="card-title"> <view class="card-title">
<view class="card-title-txt">首页应用</view> <view class="card-title-txt">首页应用</view>
<global-button type="primary" size="small" @tap="isEdit = true">编辑</global-button> <global-button type="primary" size="small" @tap="handleEdit">编辑</global-button>
</view> </view>
<view class="menu-list"> <view class="menu-list">
<menu-item <menu-item
class="menu-item" class="menu-item"
v-for="item in menuListHome" v-for="item in homeMenuList"
:data="item" :data="item"
:key="item.id" :key="item.id"
:showCount="false" :showCount="false"
:type="isEdit ? 'minus' : 'default'" :type="isEdit ? 'minus' : 'default'"
@tap="goTo" @tap="handleHomeMenu(item, 'minus')"
></menu-item> ></menu-item>
</view> </view>
</view> </view>
...@@ -33,38 +22,73 @@ ...@@ -33,38 +22,73 @@
<view class="card-title"> <view class="card-title">
<view class="card-title-txt">全部应用</view> <view class="card-title-txt">全部应用</view>
</view> </view>
<view class="menu-list" v-if="menuListNoHome.length > 0"> <view class="menu-list">
<menu-item <menu-item
class="menu-item" class="menu-item"
v-for="item in menuListNoHome" v-for="item in getMenuList"
:data="item" :data="item"
:key="item.id" :key="item.id"
:showCount="false" :showCount="false"
:type="isEdit ? 'plus' : 'default'" :type="isEdit && !item.isHome ? 'plus' : 'default'"
@tap="goTo" @tap="handleHomeMenu(item, 'plus')"
></menu-item> ></menu-item>
</view> </view>
<global-empty class="menu-empty" v-else></global-empty>
</view> </view>
</view> </view>
</global-page> </global-page>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { computed, ref } from 'vue'
import MenuItem from '../components/menu-item.vue' import MenuItem from '../components/menu-item.vue'
import { menuListHome, menuListNoHome } from '../constants/index.compositions' import useUserStore from '@/store/user'
import { onLoad } from '@dcloudio/uni-app'
import { cloneDeep } from 'lodash'
const userStore = useUserStore()
const isEdit = ref(false) const isEdit = ref(false)
const pageRef = ref()
//返回 //取消
const goBack = () => { const handleCancel = () => {
uni.navigateBack() isEdit.value = false
pageRef.value?.handleChangeEdit(false)
homeMenuList.value = cloneDeep(userStore.homeMenuList)
}
//保存
const handleSave = () => {
isEdit.value = false
pageRef.value?.handleChangeEdit(false)
userStore.homeMenuList = cloneDeep(homeMenuList.value)
uni.$message.showToast('保存菜单成功')
}
//编辑
const handleEdit = () => {
isEdit.value = true
pageRef.value?.handleChangeEdit(true)
} }
//跳转 //操作菜单
const goTo = () => { const homeMenuList = ref([])
uni.navigateTo({ url: '/pages/panel/assessment-records/list' }) onLoad(() => {
homeMenuList.value = cloneDeep(userStore.homeMenuList)
})
const handleHomeMenu = (menu, type) => {
if (isEdit.value) {
if (type == 'minus') {
homeMenuList.value = homeMenuList.value.filter((item) => item.id !== menu.id)
} else {
!menu.isHome && homeMenuList.value.push(menu)
}
}
} }
//获取全部应用
const getMenuList = computed(() => {
return userStore.menuList.map((item) => {
return {
...item,
isHome: homeMenuList.value.find((opt) => opt.id == item.id) ? true : false
}
})
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './constants/index.scss'; @import './constants/index.scss';
......
<template>
<global-page title="添加公司值班信息" showEdit @handleCancel="handleCancel" @handleSave="handleSave">
<view class="form">
<uni-forms>
<global-form-item label="公司值班经理">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="公司值班经理意见">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="公司值班经理意见描述" label-position="top">
<textarea placeholder="请输入" />
</global-form-item>
</uni-forms>
</view>
</global-page>
</template>
<script setup>
import { ref } from 'vue'
const handleCancel = () => {
uni.navigateBack()
}
const handleSave = () => {
console.log('点击保存')
}
</script>
<style lang="scss" scoped>
.form {
background: #fff;
}
</style>
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<text>{{ getIitle }}</text> <text>{{ getIitle }}</text>
</view> </view>
<view class="right" v-if="edit"> <view class="right" v-if="edit">
<global-button type="text">添加</global-button> <global-button type="text" @tap="handleAdd">添加</global-button>
</view> </view>
</view> </view>
<view class="card-content"> <view class="card-content">
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
<script setup> <script setup>
import { computed } from 'vue' import { computed } from 'vue'
const es = defineEmits(['handleAdd'])
const ps = defineProps({ const ps = defineProps({
// company,quality,appeal // company,quality,appeal
type: { type: {
...@@ -103,6 +104,9 @@ const getIitle = computed(() => { ...@@ -103,6 +104,9 @@ const getIitle = computed(() => {
} }
return '' return ''
}) })
const handleAdd = () => {
es('handleAdd')
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.card { .card {
......
<template> <template>
<global-page :showNavbar="false"> <global-page :showNavbar="false">
<template #top> <template #top>
<global-navbar title="190机型管控中心"> <global-navbar :title="details.appraisee !== '-1' ? details.appraisee : ''">
<template #left> <template #left>
<uni-icons type="left" size="16" @tap="goBack"></uni-icons> <uni-icons type="left" size="16" @tap="goBack"></uni-icons>
</template> </template>
...@@ -10,52 +10,52 @@ ...@@ -10,52 +10,52 @@
</template> </template>
</global-navbar> </global-navbar>
</template> </template>
<view class="content"> <view class="content" v-if="details">
<view class="details"> <view class="details">
<view class="details-header"> <view class="details-header">
<view class="details-header-top"> <view class="details-header-top">
<view class="txt">OPEN</view> <view class="txt">{{ details.status == 1 ? 'OPEN' : 'ClOSE' }}</view>
<score-details type="warning"></score-details> <score-details v-if="details.score > 0" :type="details.eventType == 1 ? 'success' : 'warning'">
{{ details.score }}
</score-details>
</view> </view>
<view class="details-header-bottom"> <view class="details-header-bottom">
<view class="left"> <view class="left">
<global-icon class="left-icon" icon="Vector" size="24"></global-icon> <global-icon class="left-icon" icon="Vector" size="24" color="#DD4012"></global-icon>
<view class="txt">B1004 A33</view> <view class="txt">{{ details.ac }} {{ details.acType }}</view>
</view> </view>
<view class="right">2024-04-01</view> <view class="right"><uni-dateformat :date="details.eventTime" format="yyyy-MM-dd"></uni-dateformat></view>
</view> </view>
</view> </view>
<view class="details-body"> <view class="details-body">
<view class="details-body-top"> <view class="details-body-top">
<view class="left"> <view class="left">
<global-icon icon="mind-mapping"></global-icon> <global-icon icon="mind-mapping"></global-icon>
<text>来源编号:24242424</text> <text>来源编号:{{ details.dmUid }}</text>
</view> </view>
<view class="right"> <view class="right">
中南基地 {{ details.department }}
<text>基地MCC</text> <text>{{ details.appraisee }}</text>
</view> </view>
</view> </view>
<view class="details-body-bottom"> <view class="details-body-bottom">
3月31日,天津航空6837/A320飞机执行天津=长春、天津=昆明航班,23:00落地,航后执行52A检工作,利用夜间8小时左右执行飞机检查和维修工作,次日早上8:00航前正常安排天津=乌鲁木齐=和田航班。 {{ details.eventMsg || '暂无内容~' }}
天津航空B-6837飞机3月31日夜间检查发现右发反推有油渍需停场排故,海技天津MCC发布飞机非计划停场,造成原计划4月01日B-6837执飞的天津=乌鲁木齐=和田航班延误;
为避免延误,PPD主动调整计划性工作,保障运行,协调调整定检计划,将原计划4月1-2日(停场2天)执行的32F6飞机专项定检工作调整至4
</view> </view>
</view> </view>
<view class="details-footer"> <view class="details-footer">
<view class="details-footer-top"> <view class="details-footer-top">
<global-icon icon="subscribed" color="#1D2129"></global-icon> <global-icon icon="subscribed" color="#1D2129"></global-icon>
<text>生产组织</text> <text>{{ details.examineType }}</text>
</view> </view>
<view class="details-footer-center">参考《海航技术运行品质过程考核规定》考核事项第8条..</view> <view class="details-footer-center">{{ details.examineBasis }}</view>
<view class="details-footer-bottom"> <view class="details-footer-bottom">
<view class="person-info"> <view class="person-info">
<global-icon icon="idcard"></global-icon> <global-icon icon="idcard"></global-icon>
<text>当班人员:李大同</text> <text>当班人员:{{ details.onDutyUser }}</text>
</view> </view>
<view class="person-info"> <view class="person-info">
<global-icon icon="idcard"></global-icon> <global-icon icon="idcard"></global-icon>
<text>当班人员:李大同</text> <text>值班人员:{{ details.dmName }}</text>
</view> </view>
</view> </view>
</view> </view>
...@@ -68,8 +68,49 @@ ...@@ -68,8 +68,49 @@
</template> </template>
<script setup> <script setup>
import { onLoad } from '@dcloudio/uni-app'
import CardDetails from './components/card-details.vue' import CardDetails from './components/card-details.vue'
import { ref } from 'vue'
const details = ref({
id: '1771004152946348034',
eventSource: '测试',
department: '西北基地',
appraisee: '执管MCC',
ac: 'B1012',
acOwn: 'DRJ',
acType: 'A32',
eventTime: 1711036800000,
eventMsg: '测试',
eventType: 1,
examineType: '信息管理',
examineBasis: '测试',
score: 1.0,
onDutyUser: '测试',
dmUid: '10653',
opinionType: 0,
optionSaveTime: -1,
optionSaveUid: '-1',
appealInfo: -1,
qmUid: '-1',
qualityOpinionType: -1,
qualitySaveTime: -1,
qualitySaveUid: '-1',
dmName: '唐恒山',
qmName: null,
dmSaveName: null,
qmSaveName: null,
status: 1,
dmMsg: '',
qmMsg: '',
file: '[]',
emailSendTime: 0
})
onLoad(() => {
uni.$once('appraisalRecordDetials', (data) => {
console.log(data)
})
})
//跳转 //跳转
const goTo = () => { const goTo = () => {
uni.navigateTo({ url: 'edit' }) uni.navigateTo({ url: 'edit' })
......
<template>
<global-page title="考核记录登记">
<view class="content">
<view class="form">
<uni-forms>
<global-form-item label="事件来源">
<input type="text" placeholder="请输入" />
</global-form-item>
<global-form-item label="基地/职能部门">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="考核对象">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="机号">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="客户">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="机型">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="日期">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="事件描述" label-position="top">
<textarea placeholder="请输入" />
</global-form-item>
<global-form-item label="事件类别">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="考核类型">
<global-picker></global-picker>
</global-form-item>
<global-form-item label="考核依据" label-position="top">
<textarea placeholder="请输入" />
</global-form-item>
<global-form-item label="分值">
<input type="text" placeholder="请输入" />
</global-form-item>
<global-form-item label="当班人员">
<input type="text" placeholder="请输入" />
</global-form-item>
</uni-forms>
</view>
<card-details type="company" edit @handleAdd="handleAdd"></card-details>
<card-details type="quality" edit @handleAdd="handleAdd"></card-details>
<view class="appeal">
<view class="appeal-title">
<text>申诉情况</text>
<global-picker></global-picker>
</view>
<view class="appeal-content">
<global-upload-image></global-upload-image>
</view>
</view>
</view>
<template #bottom>
<view class="submit-btn">
<global-button type="primary" size="large">保存</global-button>
</view>
</template>
</global-page>
</template>
<script setup>
import { ref } from 'vue'
import CardDetails from './components/card-details.vue'
const handleAdd = () => {
uni.navigateTo({ url: 'add' })
}
</script>
<style lang="scss" scoped>
.content {
padding-bottom: 140rpx;
.form {
background: #fff;
}
.appeal {
margin-top: 16rpx;
background: #fff;
&-title {
padding: 28rpx 32rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2rpx solid #f4f4f4;
text {
color: #1d2129;
}
}
&-content {
padding: 28rpx 32rpx;
}
}
}
.submit-btn {
padding: 24rpx 32rpx;
background-color: #fff;
}
</style>
<template>
<global-page-swiper title="考核记录" refresherEnabled loadingMoreEnabled :tabList="tabList" :api="getRqmListApi">
<template #="{ dataList }">
<view class="list">
<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>
<view class="txt">{{ item.appraisee !== '-1' ? item.appraisee : '' }}</view>
<view class="place">{{ item.department !== '-1' ? item.department : '' }}</view>
</view>
<score-details v-if="item.score > 0" :type="item.eventType == 1 ? 'success' : 'warning'">{{ item.score }}</score-details>
</view>
<view class="item-content">
{{ item.eventMsg || '暂无内容~' }}
</view>
</view>
</view>
</template>
</global-page-swiper>
</template>
<script setup>
import { ref } from 'vue'
import { getRqmListApi, getRqmOptionsApi } from '@/api/appraisal-record'
import { onLoad } from '@dcloudio/uni-app'
const tabList = ref([
{ name: 'OPEN', value: 1 },
{ name: 'CLOSE', value: 0 },
{ name: '全部', value: -1 }
])
//跳转
const goDetails = (data) => {
uni.navigateTo({
url: 'details',
success: () => {
uni.$emit('appraisalRecordDetials', data)
}
})
}
//获取选项数据
const appraisee = ref([])
const department = ref([])
const examineType = ref([])
const getRqmOptions = async () => {
const res = await getRqmOptionsApi()
if (res.code == 200) {
appraisee.value = res.data.appraisee || []
department.value = res.data.department || []
examineType.value = res.data.examineType || []
} else {
uni.$message.showToast(res.message)
}
}
onLoad(() => {
getRqmOptions()
})
</script>
<style lang="scss" scoped>
@import './constants/list.scss';
</style>
<template>
<!-- <global-page-swiper>
<template v-slot="{ dataList }">
<view class="item" v-for="(item, index) in dataList" :key="index">
<view class="item-title">{{ index }}我是标题</view>
<view class="item-detail">{{ index }}我是详情</view>
<view class="item-line"></view>
</view>
</template>
</global-page-swiper> -->
</template>
<script setup>
import { ref, watch } from 'vue'
</script>
<style>
.item {
position: relative;
height: 150rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0rpx 30rpx;
}
.item-detail {
padding: 5rpx 15rpx;
border-radius: 10rpx;
font-size: 28rpx;
color: white;
background-color: #007aff;
}
.item-line {
position: absolute;
bottom: 0rpx;
left: 0rpx;
height: 1px;
width: 100%;
background-color: #eeeeee;
}
</style>
<template>
<global-page title="考核记录登记">
<view class="content">
<view class="form">
<view class="form-item">
<view class="form-item-label">事件来源</view>
<input class="form-item-input" type="text" placeholder="请输入" />
</view>
<view class="form-item">
<view class="form-item-label">基地/职能部门</view>
<global-picker v-model="select" dictkey="hobby"></global-picker>
</view>
<view class="form-item">
<view class="form-item-label">考核对象</view>
<global-picker></global-picker>
</view>
<view class="form-item">
<view class="form-item-label">机号</view>
<global-picker></global-picker>
</view>
<view class="form-item">
<view class="form-item-label">客户</view>
<global-picker></global-picker>
</view>
<view class="form-item">
<view class="form-item-label">机型</view>
<global-picker></global-picker>
</view>
<view class="form-item">
<view class="form-item-label">日期</view>
<global-picker></global-picker>
</view>
<view class="form-item textarea">
<view class="form-item-label">事件描述</view>
<textarea placeholder="请输入" />
</view>
<view class="form-item">
<view class="form-item-label">事件类别</view>
<global-picker></global-picker>
</view>
<view class="form-item">
<view class="form-item-label">考核类型</view>
<global-picker></global-picker>
</view>
<view class="form-item textarea">
<view class="form-item-label">考核依据</view>
<textarea placeholder="请输入" />
</view>
<view class="form-item">
<view class="form-item-label">分值</view>
<input class="form-item-input" type="text" placeholder="请输入" />
</view>
<view class="form-item">
<view class="form-item-label">当班人员</view>
<input class="form-item-input" type="text" placeholder="请输入" />
</view>
</view>
<card-details type="company" edit></card-details>
<card-details type="quality" edit></card-details>
</view>
<template #bottom>
<view class="submit-btn">
<global-button type="primary" size="large">保存</global-button>
</view>
</template>
</global-page>
</template>
<script setup>
import { ref } from 'vue'
import CardDetails from './components/card-details.vue'
const select = ref('1')
</script>
<style lang="scss" scoped>
.content {
padding-bottom: 140rpx;
.form {
background: #fff;
&-item {
display: flex;
justify-content: space-between;
padding: 24rpx 32rpx;
border-bottom: 2rpx solid #f4f4f4;
&-label {
color: rgba(0, 0, 0, 0.9);
}
&-input {
text-align: right;
}
&.textarea {
flex-direction: column;
textarea {
margin-top: 8rpx;
height: 80rpx;
}
}
}
}
}
.submit-btn {
padding: 24rpx 32rpx;
background-color: #fff;
}
</style>
<template>
<global-page-swiper title="考核记录" refresherEnabled loadingMoreEnabled :tabList="tabList">
<template #="{ dataList }">
<view class="list">
<view class="item" v-for="(item, index) in dataList" :key="index" @tap="goTo">
<view class="item-title">
<view class="desc">
<view class="type">OPEN</view>
<view class="txt">190机型管控中心</view>
<view class="place">华北基地</view>
</view>
<score-details :type="index % 2 == 0 ? 'success' : 'warning'"></score-details>
</view>
<view class="item-content">
3月31日,天津航空6837/A320飞机执行天津=长春、天津=昆明航班,23:00落地,航后执行52A检工作,利用夜间8小时左右执行飞机检查和维修工
</view>
</view>
</view>
</template>
</global-page-swiper>
</template>
<script setup>
import { ref } from 'vue'
const tabList = ref(['OPEN', 'CLOSE', '全部'])
//跳转
const goTo = () => {
uni.navigateTo({ url: 'details' })
}
</script>
<style lang="scss" scoped>
@import './constants/list.scss';
</style>
...@@ -62,6 +62,7 @@ const getCount = computed(() => { ...@@ -62,6 +62,7 @@ const getCount = computed(() => {
margin-top: 16rpx; margin-top: 16rpx;
color: #1d2129; color: #1d2129;
font-size: 30rpx; font-size: 30rpx;
line-height: 40rpx;
} }
.circle { .circle {
width: 32rpx; width: 32rpx;
......
import { computed, ref } from 'vue'
//全部菜单
export const menuList = [
{ id: 1, name: '信息通报', icon: 'xxtb', group: '技术支援', count: 12, home: true },
{ id: 2, name: '机队状态', icon: 'jdzt', group: '技术支援', count: 0, home: true },
{ id: 3, name: '支援申请', icon: 'zysq', group: '技术支援', count: 0, home: true },
{ id: 4, name: '工作指令', icon: 'gzzl', group: '技术支援', count: 0, home: true },
{ id: 5, name: '技术评估', icon: 'jspg', group: '技术支援', count: 0, home: true },
{ id: 6, name: '运行调查', icon: 'yxdc', group: '维修控制', count: 0, home: true },
{ id: 7, name: '运行决策', icon: 'yxjc', group: '维修控制', count: 0, home: true },
{ id: 8, name: '布置工作', icon: 'bzgz', group: '维修控制', count: 0, home: true },
{ id: 9, name: '航站管理', icon: 'hzgl', group: '航站管理', count: 0, home: true },
{ id: 10, name: '协议单位', icon: 'xydw', group: '航站管理', count: 0, home: true },
{ id: 11, name: '不正常事件', icon: 'bzcsj', group: '运行品质', count: 0, home: false },
{ id: 12, name: '考核记录', icon: 'khjl', group: '运行品质', count: 0, home: false },
{ id: 13, name: 'AOG任务', icon: 'AOG', group: '运行品质', count: 0, home: false },
{ id: 14, name: 'MCO', icon: 'MCO', group: '运行品质', count: 0, home: false },
{ id: 15, name: '航班保障', icon: 'hbbz', group: '运行品质', count: 0, home: false }
]
export const allMenuItem = { id: 999, name: '全部菜单', icon: 'all', group: '', count: 0, home: true }
//获取首页菜单
export const menuListHome = computed(() => {
return menuList.filter((item) => item.home)
})
//获取除首页菜单
export const menuListNoHome = computed(() => {
return menuList.filter((item) => !item.home)
})
//获取分组菜单
export const menuListGroup = computed(() => {
return menuList.reduce((groups, item) => {
// 如果该组不存在,则创建一个新组
if (!groups[item.group]) {
groups[item.group] = []
}
// 将当前项添加到对应的组中
groups[item.group].push(item)
return groups
}, {})
})
...@@ -8,16 +8,16 @@ ...@@ -8,16 +8,16 @@
<scroll-view class="tab-content" scroll-y="true"> <scroll-view class="tab-content" scroll-y="true">
<view class="tab-content-item" v-if="activeIndex == 0"> <view class="tab-content-item" v-if="activeIndex == 0">
<view class="menu-list"> <view class="menu-list">
<menu-item class="menu-item" v-for="item in menuListHome" :data="item" :key="item.id" @tap="goTo"></menu-item> <menu-item class="menu-item" v-for="item in userStore.homeMenuList" :data="item" :key="item.id" @tap="goTo(item.url)"></menu-item>
<menu-item class="menu-item" :data="allMenuItem" @tap="goAppCenter"></menu-item> <menu-item class="menu-item" :data="userStore.allMenuItem" @tap="goAppCenter"></menu-item>
</view> </view>
</view> </view>
<view class="tab-content-item" v-if="activeIndex == 1"> <view class="tab-content-item" v-if="activeIndex == 1">
<view class="menu-content"> <view class="menu-content">
<view class="menu-content-item" v-for="(value, key) in menuListGroup" :key="key"> <view class="menu-content-item" v-for="(value, key) in userStore.getGroupMenuList" :key="key">
<view class="menu-title">{{ key }}</view> <view class="menu-title">{{ key }}</view>
<view class="menu-list"> <view class="menu-list">
<menu-item class="menu-item" v-for="item in value" :data="item" :key="item.id" @tap="goTo"></menu-item> <menu-item class="menu-item" v-for="item in value" :data="item" :key="item.id" @tap="goTo(item.url)"></menu-item>
</view> </view>
<view class="menu-line"></view> <view class="menu-line"></view>
</view> </view>
...@@ -30,16 +30,17 @@ ...@@ -30,16 +30,17 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import MenuItem from './components/menu-item.vue' import MenuItem from './components/menu-item.vue'
import { menuListHome, menuListGroup, allMenuItem } from './constants/index.compositions' import useUserStore from '@/store/user'
const userStore = useUserStore()
// 获取屏幕边界到安全区域距离 // 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync() const { safeAreaInsets } = uni.getSystemInfoSync()
//分类 //分类
const tabNav = ref(['常用', '分组']) const tabNav = ref(['常用', '分组'])
const activeIndex = ref(0) const activeIndex = ref(0)
//跳转 //跳转
const goTo = () => { const goTo = (url) => {
uni.navigateTo({ url: '/pages/panel/assessment-records/list' }) url && uni.navigateTo({ url })
} }
//跳转应用中心 //跳转应用中心
const goAppCenter = () => { const goAppCenter = () => {
......
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { cloneDeep } from 'lodash'
const menuList = [
{ id: 1, name: '信息通报', icon: 'xxtb', group: '技术支援', count: 12 },
{ id: 2, name: '机队状态', icon: 'jdzt', group: '技术支援', count: 0 },
{ id: 3, name: '支援申请', icon: 'zysq', group: '技术支援', count: 0 },
{ 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: 8, name: '布置工作', icon: 'bzgz', group: '维修控制', count: 0 },
{ id: 9, name: '航站管理', icon: 'hzgl', group: '航站管理', count: 0 },
{ id: 10, name: '协议单位', icon: 'xydw', group: '航站管理', count: 0 },
{ id: 11, name: '不正常事件', icon: 'bzcsj', group: '运行品质', count: 0 },
{ id: 12, name: '考核记录', icon: 'khjl', group: '运行品质', count: 0, url: '/pages/panel/appraisal-record/list' },
{ id: 13, name: 'AOG任务', icon: 'AOG', group: '运行品质', count: 0 },
{ id: 14, name: 'MCO', icon: 'MCO', group: '运行品质', count: 0 },
{ id: 15, name: '航班保障', icon: 'hbbz', group: '运行品质', count: 0 }
]
const useUserStore = defineStore('user', { const useUserStore = defineStore('user', {
state: () => { state: () => {
return { return {
token: '', token: '',
user_info: undefined user_info: undefined,
menuList: cloneDeep(menuList),
homeMenuList: cloneDeep(menuList),
allMenuItem: { id: 999, name: '全部菜单', icon: 'all', group: '', count: 0 }
}
},
getters: {
//获取分组菜单
getGroupMenuList(state) {
return state.menuList.reduce((groups, item) => {
// 如果该组不存在,则创建一个新组
if (!groups[item.group]) {
groups[item.group] = []
}
// 将当前项添加到对应的组中
groups[item.group].push(item)
return groups
}, {})
} }
}, },
getters: {},
actions: { actions: {
//用户登录 //用户登录
setUserInfo(data) { setUserInfo(data) {
...@@ -35,8 +66,8 @@ const useUserStore = defineStore('user', { ...@@ -35,8 +66,8 @@ const useUserStore = defineStore('user', {
}, },
getItem(key) { getItem(key) {
return uni.getStorageSync(key) return uni.getStorageSync(key)
}, }
}, }
}, }
}) })
export default useUserStore export default useUserStore
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* 4. 添加 token 请求头标识 * 4. 添加 token 请求头标识
*/ */
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/user'
const baseURL = 'https://hna-platform.anyremote.cn' const baseURL = 'https://hna-platform.anyremote.cn'
...@@ -29,7 +29,8 @@ class ServiceLoading { ...@@ -29,7 +29,8 @@ class ServiceLoading {
} }
this.count++ this.count++
uni.showLoading({ uni.showLoading({
title: loadingText title: loadingText,
mask: true
}); });
} }
} }
...@@ -95,7 +96,7 @@ uni.addInterceptor('uploadFile', httpInterceptor) ...@@ -95,7 +96,7 @@ uni.addInterceptor('uploadFile', httpInterceptor)
* 3.2 其他错误 -> 根据后端错误信息轻提示 * 3.2 其他错误 -> 根据后端错误信息轻提示
* 3.3 网络错误 -> 提示用户换网络 * 3.3 网络错误 -> 提示用户换网络
*/ */
// 2.2 添加类型,支持泛型 // 2.2 添加类型
export const http = (options) => { export const http = (options) => {
// 1. 返回 Promise 对象 // 1. 返回 Promise 对象
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
...@@ -115,21 +116,14 @@ export const http = (options) => { ...@@ -115,21 +116,14 @@ export const http = (options) => {
reject(res) reject(res)
} else { } else {
// 其他错误 -> 根据后端错误信息轻提示 // 其他错误 -> 根据后端错误信息轻提示
uni.showToast({ uni.$message.showToast(res.data.msg || '请求错误')
icon: 'none',
mask: true,
title: res.data.msg || '请求错误',
})
reject(res) reject(res)
} }
}, },
// 响应失败 // 响应失败
fail(err) { fail(err) {
serviceLoading.close() serviceLoading.close()
uni.showToast({ uni.$message.showToast('网络错误,换个网络试试')
icon: 'none',
title: '网络错误,换个网络试试',
})
reject(err) reject(err)
}, },
}) })
......
// utils/message.js // utils/message.js
export default { export default {
// 成功提示 showToast(msg, options) {
success(options) {
uni.showToast({ uni.showToast({
title: options.title || '操作成功', title: msg || '操作失败',
icon: 'success',
duration: 2000,
...options
});
},
// 错误提示
error(options) {
uni.showToast({
title: options.title || '操作失败',
icon: 'none', icon: 'none',
duration: 2000, duration: 2000,
...options ...options
......
module.exports = {
transpileDependencies: ['@dcloudio/uni-ui']
}
\ No newline at end of file
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