Merge branch 'main' of http://175.6.124.250:3100/luozhun/policeSecurity
|
@ -1,3 +1,10 @@
|
||||||
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
|
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
|
||||||
TARO_APP_ID="wx0acd1c4fcf94bdd3"
|
TARO_APP_ID="wx0acd1c4fcf94bdd3"
|
||||||
|
# TARO_APP_BASE_API="http://172.10.10.93:8765"
|
||||||
TARO_APP_BASE_API="http://172.10.10.93:8765"
|
TARO_APP_BASE_API="http://172.10.10.93:8765"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# minio
|
||||||
|
TARO_APP_MINIO_URL=http://118.253.177.137:9000
|
||||||
|
TARO_APP_MINIO_BUCKET=police-security-dev
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
# TARO_APP_ID="生产环境下的小程序appid"
|
# TARO_APP_ID="wx0acd1c4fcf94bdd3"
|
||||||
|
TARO_APP_BASE_API="https://www.hnjinglian.cn:5678"
|
||||||
|
|
||||||
|
# minio
|
||||||
|
TARO_APP_MINIO_URL=https://www.hnjinglian.cn:9002
|
||||||
|
TARO_APP_MINIO_BUCKET=police-security
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
# TARO_APP_ID="测试环境下的小程序appid"
|
|
|
@ -5,11 +5,14 @@
|
||||||
"appid": "touristappid",
|
"appid": "touristappid",
|
||||||
"setting": {
|
"setting": {
|
||||||
"urlCheck": false,
|
"urlCheck": false,
|
||||||
"es6": false,
|
"es6": true,
|
||||||
"enhance": false,
|
"enhance": false,
|
||||||
|
"minified": true,
|
||||||
|
"minifyWXSS": true,
|
||||||
|
"minifyWXML": true,
|
||||||
"compileHotReLoad": false,
|
"compileHotReLoad": false,
|
||||||
"postcss": false,
|
"postcss": true,
|
||||||
"minified": false
|
"minified": true
|
||||||
},
|
},
|
||||||
"compileType": "miniprogram"
|
"compileType": "miniprogram"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,24 @@ export default defineAppConfig({
|
||||||
'myProject/projectDetails/projectDetails',
|
'myProject/projectDetails/projectDetails',
|
||||||
'securityUserForm/securityUserForm',
|
'securityUserForm/securityUserForm',
|
||||||
]
|
]
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
root: "subPages/police",
|
root: "subPages/police",
|
||||||
pages: [
|
pages: [
|
||||||
|
'dailyInspection/dailyInspection',
|
||||||
'myEnterprisesUnit/myEnterprisesUnit',
|
'myEnterprisesUnit/myEnterprisesUnit',
|
||||||
'myEnterprisesUnit/projectDetails/projectDetails'
|
'myEnterprisesUnit/projectDetails/projectDetails'
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
root: "subPages/select",
|
||||||
|
pages: [
|
||||||
|
'dailyLife/dailyLife',
|
||||||
|
'signature/signature'
|
||||||
|
]
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
window: {
|
window: {
|
||||||
backgroundTextStyle: 'light',
|
backgroundTextStyle: 'light',
|
||||||
navigationBarBackgroundColor: '#4e87ff',
|
navigationBarBackgroundColor: '#4e87ff',
|
||||||
|
|
|
@ -24,6 +24,40 @@ const App = createApp({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onShow(){
|
||||||
|
const updateManager = Taro.getUpdateManager()
|
||||||
|
updateManager.onCheckForUpdate(function(res) {
|
||||||
|
// 请求完新版本信息的回调
|
||||||
|
if (res.hasUpdate) {
|
||||||
|
// 新版本已经下载好,调用 applyUpdate 应用新版本并重启
|
||||||
|
updateManager.applyUpdate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
updateManager.onUpdateReady(function() {
|
||||||
|
// 新版本已经准备好,可以提示用户更新
|
||||||
|
Taro.showModal({
|
||||||
|
title: '更新提示',
|
||||||
|
content: '发现新版本,是否重启应用?',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 新的版本已经准备好,调用 applyUpdate 应用新版本
|
||||||
|
updateManager.applyUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(res=>{
|
||||||
|
console.log(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
updateManager.onUpdateFailed(function() {
|
||||||
|
// 新版本下载失败,可进行一些提示用户的操作
|
||||||
|
Taro.showModal({
|
||||||
|
title: '已有新版本',
|
||||||
|
content: '请删除当前小程序,重新从搜索界面打开获取最新版本',
|
||||||
|
}).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
|
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 500 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 1.2 KiB |
|
@ -20,7 +20,7 @@ export const MINI_PROGRAM_USER_CONFIG: Record<MiniProgramUserIdentity, UserConfi
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pagePath: 'pages/police/mine/index',
|
pagePath: 'pages/police/mine/index',
|
||||||
text: '警察我的',
|
text: '我的',
|
||||||
iconPath: "assets/mine/my.png",
|
iconPath: "assets/mine/my.png",
|
||||||
selectedIconPath: "assets/mine/my-active.png"
|
selectedIconPath: "assets/mine/my-active.png"
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,7 @@ export const MINI_PROGRAM_USER_CONFIG: Record<MiniProgramUserIdentity, UserConfi
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pagePath: 'pages/projectManager/mine/index',
|
pagePath: 'pages/projectManager/mine/index',
|
||||||
text: '项目经理我的',
|
text: '我的',
|
||||||
iconPath: "assets/mine/my.png",
|
iconPath: "assets/mine/my.png",
|
||||||
selectedIconPath: "assets/mine/my-active.png"
|
selectedIconPath: "assets/mine/my-active.png"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,43 +1,68 @@
|
||||||
|
.nameTitle {
|
||||||
|
position: absolute;
|
||||||
|
top: 19%;
|
||||||
|
left: 55px;
|
||||||
|
height: 125rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
width: 650rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
box-shadow: 0px 10px 10px -4px #e3e3e3;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.itemSchool {
|
||||||
|
border-right: solid 1.5rpx #dadada;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 25%;
|
||||||
|
font-size: 24px
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemSchool text:nth-child(1) {
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
color: #898a8a;
|
||||||
|
margin-left: -8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nameTitle .itemSchool:nth-child(4) {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
.swiperDemoItem {
|
.swiperDemoItem {
|
||||||
color: #3886d0;
|
color: #3886d0;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 20px 0 0 50px;
|
padding: 20px 0 0 50px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
|
margin-top: 70px;
|
||||||
|
|
||||||
.swiperDemoIndex {
|
.swiperDemoIndex {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 45px;
|
height: 45px;
|
||||||
background-image: linear-gradient(to bottom, #5d9cf9, #317ad9);
|
background-image: linear-gradient(to bottom, #5d9cf9, #317ad9);
|
||||||
//background: rgb();
|
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.Module {
|
||||||
|
background-color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
.subModule {
|
.subModule {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-right: -3px;
|
|
||||||
margin-left: -1px;
|
|
||||||
|
|
||||||
.subModuleItem {
|
.subModuleItem {
|
||||||
width: 33%;
|
width: 246rpx;
|
||||||
height: 180rpx;
|
height: 140rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-bottom: 10rpx;
|
padding-bottom: 10rpx;
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-left: 0;
|
|
||||||
margin-top: -1px;
|
|
||||||
|
|
||||||
.subModuleIndex {
|
.subModuleIndex {
|
||||||
width: 65rpx;
|
width: 45rpx;
|
||||||
height: 65rpx;
|
height: 45rpx;
|
||||||
|
|
||||||
image {
|
image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -45,3 +70,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
.swiperDemoItem {
|
||||||
|
color: #3886d0;
|
||||||
|
display: flex;
|
||||||
|
padding: 20px 0 0 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 70rpx;
|
||||||
|
|
||||||
|
.swiperDemoIndex {
|
||||||
|
width: 15px;
|
||||||
|
height: 45px;
|
||||||
|
background-image: linear-gradient(to bottom, #5d9cf9, #317ad9);
|
||||||
|
//background: rgb();
|
||||||
|
border-radius: 20px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.subModule {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-right: -3px;
|
||||||
|
margin-left: -1px;
|
||||||
|
|
||||||
|
.subModuleItem {
|
||||||
|
width: 33%;
|
||||||
|
height: 180rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-left: 0;
|
||||||
|
margin-top: -1px;
|
||||||
|
|
||||||
|
.subModuleIndex {
|
||||||
|
width: 65rpx;
|
||||||
|
height: 65rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,56 +3,114 @@
|
||||||
<view class="swiperDemo">
|
<view class="swiperDemo">
|
||||||
<nut-swiper ref="swiperRef" pagination-visible pagination-color="#e53e31" :auto-play="3000" :init-page="0">
|
<nut-swiper ref="swiperRef" pagination-visible pagination-color="#e53e31" :auto-play="3000" :init-page="0">
|
||||||
<nut-swiper-item v-for="(item, index) in list" :key="index" style="height: 180px">
|
<nut-swiper-item v-for="(item, index) in list" :key="index" style="height: 180px">
|
||||||
<image src="@/assets/images/01.png" alt="" style="height: 100%; width: 100%" draggable="false"/>
|
<image :src="item" alt="" style="height: 100%; width: 100%" draggable="false" />
|
||||||
</nut-swiper-item>
|
</nut-swiper-item>
|
||||||
</nut-swiper>
|
</nut-swiper>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="nameTitle">
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>单位数量</text>
|
||||||
|
<text style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 80px; text-align: center">{{ numberStatistics.enterprisesUnitCount }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>服务项目</text>
|
||||||
|
<text>
|
||||||
|
{{ numberStatistics.serviceProjectCount }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>有保安证人员</text>
|
||||||
|
<text>{{ numberStatistics.securityUserCount }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>无保安证人员</text>
|
||||||
|
<text>{{ numberStatistics.noCardSecurityUserCount }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="swiperDemoItem">
|
<view class="swiperDemoItem">
|
||||||
<view class="swiperDemoIndex"></view>
|
<view class="swiperDemoIndex"></view>
|
||||||
<view>请选择</view>
|
<view>请选择</view>
|
||||||
</view>
|
</view>
|
||||||
<!--九宫格-->
|
<!--九宫格-->
|
||||||
<view>
|
<view class="Module">
|
||||||
<view class="subModule">
|
<view class="subModule">
|
||||||
<view class="subModuleItem" v-for="item in subModuleList" :key="item.id" @click="subNavigation(item.url)">
|
<view class="subModuleItem" v-for="item in subModuleList" :key="item.id" @click="subNavigation(item.url)">
|
||||||
<view class="subModuleIndex">
|
<view class="subModuleIndex">
|
||||||
<image :src="item.icon"></image>
|
<image :src="item.icon"></image>
|
||||||
</view>
|
</view>
|
||||||
<view style=" font-size: 12px;color: #414141;margin-top: 9px">{{ item.name }}</view>
|
<view style="font-size: 12px; color: #414141; margin-top: 5px">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view style="background-color: #e9eef4; height: 15rpx"></view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from '@tarojs/taro'
|
||||||
import icon from '@/assets/images/project.png'
|
import icon from '@/assets/images/project.png'
|
||||||
|
import icon01 from '@/assets/images/回单.jpg'
|
||||||
|
import icon02 from '@/assets/images/工单.jpg'
|
||||||
|
import icon03 from '@/assets/images/排名.jpg'
|
||||||
|
import icon04 from '@/assets/images/法制宣传.jpg'
|
||||||
|
import icon06 from '@/assets/images/警保风采.jpg'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import api from '@/request'
|
||||||
const list = ref(['https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',])
|
import { DataStatisticsRes } from '@/types/pages/police'
|
||||||
|
const list = ref([process.env.TARO_APP_MINIO_URL + '/police-security/2024/11/5/dunpai.jpg'])
|
||||||
const swiperRef = ref() //轮播图
|
const swiperRef = ref() //轮播图
|
||||||
const subModuleList = ref([
|
const subModuleList = ref([
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
name: '企事业单位',
|
name: '项目管理',
|
||||||
url: '/subPages/police/myEnterprisesUnit/myEnterprisesUnit'
|
url: '/subPages/police/myEnterprisesUnit/myEnterprisesUnit',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
icon: icon,
|
icon: icon02,
|
||||||
name: '警保风采',
|
name: '监督考核',
|
||||||
url: ''
|
url: '/subPages/police/dailyInspection/dailyInspection',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
icon: icon,
|
icon: icon03,
|
||||||
name: '待定',
|
name: '考核排名',
|
||||||
url: ''
|
url: '',
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
icon: icon06,
|
||||||
|
name: '警保风采',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
icon: icon04,
|
||||||
|
name: '法制宣传',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
icon: icon01,
|
||||||
|
name: '整改回单',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const subNavigation = async (url: string) => Taro.navigateTo({url})
|
const numberStatistics = ref<DataStatisticsRes>({
|
||||||
|
enterprisesUnitCount: 0,
|
||||||
|
serviceProjectCount: 0,
|
||||||
|
securityUserCount: 0,
|
||||||
|
noCardSecurityUserCount: 0,
|
||||||
|
})
|
||||||
|
const dataStatistics = async () => {
|
||||||
|
const resp = await api.get<DataStatisticsRes>('/policeIndex/dataStatistics')
|
||||||
|
numberStatistics.value = resp.data as DataStatisticsRes
|
||||||
|
}
|
||||||
|
onMounted(async () => {
|
||||||
|
await dataStatistics()
|
||||||
|
})
|
||||||
|
|
||||||
|
const subNavigation = async (url: string) => Taro.navigateTo({ url })
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
<template>
|
||||||
|
<view class="search" id="search">
|
||||||
|
<nut-input v-model="valueInput" @input="searchInput" placeholder="请进行搜索"></nut-input>
|
||||||
|
<view v-if="valueInput">
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in searchResults" :key="item.id">{{item}}</li>
|
||||||
|
</ul>
|
||||||
|
</view>
|
||||||
|
<view v-else >
|
||||||
|
没有找到相关结果
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {onMounted, ref,} from "vue";
|
||||||
|
const valueInput = ref('')
|
||||||
|
const list = ref([])
|
||||||
|
const dataList = ref([
|
||||||
|
{
|
||||||
|
id:0,
|
||||||
|
value:'齐家园'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:1,
|
||||||
|
value:'刘德华'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:2,
|
||||||
|
value:'张学友'
|
||||||
|
},{
|
||||||
|
id:3,
|
||||||
|
value:'黎明'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:4,
|
||||||
|
value:'家具城'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:5,
|
||||||
|
value:'左岸春天'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:6,
|
||||||
|
value:'麦德龙商城'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:7,
|
||||||
|
value:'世纪酒店'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:8,
|
||||||
|
value:'四方小学'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:9,
|
||||||
|
value:'海洋半岛'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:10,
|
||||||
|
value:'育英小学'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:11,
|
||||||
|
value:'明德小学'
|
||||||
|
},{
|
||||||
|
id:12,
|
||||||
|
value:'希望小学',
|
||||||
|
}
|
||||||
|
])
|
||||||
|
const searchResults = ref([])
|
||||||
|
const searchInput = (e:any)=>{
|
||||||
|
valueInput.value = e.target.value
|
||||||
|
if (!valueInput.value) {
|
||||||
|
searchResults.value = []
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
searchResults.value = list.value.filter(item =>
|
||||||
|
item.toLowerCase().includes(valueInput.value.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(()=>{
|
||||||
|
dataList.value.map((item)=>{
|
||||||
|
return list.value.push(item.value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.search{
|
||||||
|
padding: 0 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #4e71f2;
|
||||||
|
margin: 1px 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 30%;
|
||||||
|
.ceShi{
|
||||||
|
height: 300px;
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nut-input{
|
||||||
|
padding: 20rpx 20rpx;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,71 @@
|
||||||
|
.public {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.public-container {
|
||||||
|
height: 320rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-image: url('../../../assets/images/banner.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 45rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.contacts {
|
||||||
|
height: 75rpx;
|
||||||
|
width: 75rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: solid 1px gray;
|
||||||
|
.image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tips-text {
|
||||||
|
display: flex;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 50rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.exit {
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: solid 0.5px #ebebf7;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: #7d7d7d;
|
||||||
|
.exitItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
.exitItemIndex {
|
||||||
|
height: 40rpx;
|
||||||
|
width: 40rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
line-height: 48rpx;
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.microscope {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 2px #ccc;
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
border-bottom: white;
|
||||||
|
border-left: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,80 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view class="public">
|
||||||
警察我的
|
<!-- 公安-->
|
||||||
|
<view class="public-container" >
|
||||||
|
<view class="contacts">
|
||||||
|
<image src="@/assets/logo/avatar1.png" mode="scaleToFill" class="image" />
|
||||||
|
</view>
|
||||||
|
<view class="tips-text">
|
||||||
|
<view style="font-size: 15px;">名字</view>
|
||||||
|
<view style="font-size: 12px;">
|
||||||
|
<text style="margin-right: 5px">部门 </text>
|
||||||
|
<text>未选择单位</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 用户信息 -->
|
||||||
|
<view class="userIndex">
|
||||||
|
<view class="exit" v-for="item in datalist" :key="item.value" @click="addExit(item.value)">
|
||||||
|
<view class="exitItem">
|
||||||
|
<!-- <view class="exitItemIndex">-->
|
||||||
|
<!-- <image :src="item.url" mode="scaleToFill" class="image" />-->
|
||||||
|
<!-- </view>-->
|
||||||
|
<text style="margin-left: 30rpx;font-size: 12px;">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<view style="margin-right: 40rpx">
|
||||||
|
<text class="microscope"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 退出弹框-->
|
||||||
|
<nut-dialog
|
||||||
|
content="是否退出登录?"
|
||||||
|
v-model:visible="visible" @cancel="visible = false" @ok="onOk"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import './index.scss'
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {useUserStore} from "@/store/userStore";
|
||||||
|
import {useTabBarStore} from "@/store/tabBarStore"
|
||||||
|
import Taro from "@tarojs/taro";
|
||||||
|
|
||||||
|
const {setSelected} = useTabBarStore()
|
||||||
|
const {resetUserInfo} = useUserStore()
|
||||||
|
const visible = ref<boolean>(false)
|
||||||
|
const datalist = ref([
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: '简介',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
name: '退出登录',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
name: '修改用户信息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
name: '意见收集',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
const addExit = (index:number)=>{
|
||||||
|
switch (index) {
|
||||||
|
case 1:
|
||||||
|
visible.value = true
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const onOk = ()=>{
|
||||||
|
resetUserInfo()
|
||||||
|
setSelected(0)
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: "/pages/login/login",
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,43 +1,68 @@
|
||||||
|
.nameTitle {
|
||||||
|
position: absolute;
|
||||||
|
top: 19%;
|
||||||
|
left: 55px;
|
||||||
|
height: 125rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
width: 650rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
box-shadow: 0px 10px 10px -4px #e3e3e3;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.itemSchool {
|
||||||
|
border-right: solid 1.5rpx #dadada;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 25%;
|
||||||
|
font-size: 24px
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemSchool text:nth-child(1) {
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
color: #898a8a;
|
||||||
|
margin-left: -8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nameTitle .itemSchool:nth-child(4) {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
.swiperDemoItem {
|
.swiperDemoItem {
|
||||||
color: #3886d0;
|
color: #3886d0;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 20px 0 0 50px;
|
padding: 20px 0 0 50px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
|
margin-top: 70px;
|
||||||
|
|
||||||
.swiperDemoIndex {
|
.swiperDemoIndex {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 45px;
|
height: 45px;
|
||||||
background-image: linear-gradient(to bottom, #5d9cf9, #317ad9);
|
background-image: linear-gradient(to bottom, #5d9cf9, #317ad9);
|
||||||
//background: rgb();
|
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.Module {
|
||||||
|
background-color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
.subModule {
|
.subModule {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-right: -3px;
|
|
||||||
margin-left: -1px;
|
|
||||||
|
|
||||||
.subModuleItem {
|
.subModuleItem {
|
||||||
width: 33%;
|
width: 246rpx;
|
||||||
height: 180rpx;
|
height: 140rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-bottom: 10rpx;
|
padding-bottom: 10rpx;
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-left: 0;
|
|
||||||
margin-top: -1px;
|
|
||||||
|
|
||||||
.subModuleIndex {
|
.subModuleIndex {
|
||||||
width: 65rpx;
|
width: 45rpx;
|
||||||
height: 65rpx;
|
height: 45rpx;
|
||||||
|
|
||||||
image {
|
image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -46,3 +71,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,56 +3,101 @@
|
||||||
<view class="swiperDemo">
|
<view class="swiperDemo">
|
||||||
<nut-swiper ref="swiperRef" pagination-visible pagination-color="#e53e31" :auto-play="3000" :init-page="0">
|
<nut-swiper ref="swiperRef" pagination-visible pagination-color="#e53e31" :auto-play="3000" :init-page="0">
|
||||||
<nut-swiper-item v-for="(item, index) in list" :key="index" style="height: 180px">
|
<nut-swiper-item v-for="(item, index) in list" :key="index" style="height: 180px">
|
||||||
<image src="@/assets/images/01.png" alt="" style="height: 100%; width: 100%" draggable="false"/>
|
<image :src="item" alt="" style="height: 100%; width: 100%" draggable="false" />
|
||||||
|
<view>1123</view>
|
||||||
</nut-swiper-item>
|
</nut-swiper-item>
|
||||||
</nut-swiper>
|
</nut-swiper>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="nameTitle">
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>单位数量</text>
|
||||||
|
<text style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 80px; text-align: center">51</text>
|
||||||
|
</view>
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>服务项目</text>
|
||||||
|
<text> 13123 </text>
|
||||||
|
</view>
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>有保安证人员</text>
|
||||||
|
<text> 1000</text>
|
||||||
|
</view>
|
||||||
|
<view class="itemSchool">
|
||||||
|
<text>无保安证人员</text>
|
||||||
|
<text> 140</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="swiperDemoItem">
|
<view class="swiperDemoItem">
|
||||||
<view class="swiperDemoIndex"></view>
|
<view class="swiperDemoIndex"></view>
|
||||||
<view>请选择</view>
|
<view>请选择</view>
|
||||||
</view>
|
</view>
|
||||||
<!--九宫格-->
|
<!--九宫格-->
|
||||||
<view>
|
<view class="Module">
|
||||||
<view class="subModule">
|
<view class="subModule">
|
||||||
<view class="subModuleItem" v-for="item in subModuleList" :key="item.id" @click="subNavigation(item.url)">
|
<view class="subModuleItem" v-for="item in subModuleList" :key="item.id" @click="subNavigation(item.url)">
|
||||||
<view class="subModuleIndex">
|
<view class="subModuleIndex">
|
||||||
<image :src="item.icon"></image>
|
<image :src="item.icon"></image>
|
||||||
</view>
|
</view>
|
||||||
<view style=" font-size: 12px;color: #414141;margin-top: 9px">{{ item.name }}</view>
|
<view style="font-size: 12px; color: #414141; margin-top: 5px">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view style="background-color: #e9eef4; height: 15rpx"></view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from '@tarojs/taro'
|
||||||
import icon from '@/assets/images/project.png'
|
import icon from '@/assets/images/project.png'
|
||||||
|
import icon01 from '@/assets/images/回单.jpg'
|
||||||
|
import icon02 from '@/assets/images/工单.jpg'
|
||||||
|
import icon03 from '@/assets/images/排名.jpg'
|
||||||
|
import icon04 from '@/assets/images/法制宣传.jpg'
|
||||||
|
import icon06 from '@/assets/images/警保风采.jpg'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const list = ref(['https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',])
|
const list = ref([process.env.TARO_APP_MINIO_URL + '/police-security/2024/11/5/dunpai.jpg'])
|
||||||
const swiperRef = ref() //轮播图
|
const swiperRef = ref() //轮播图
|
||||||
const subModuleList = ref([
|
const subModuleList = ref([
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
name: '我的项目',
|
name: '项目管理',
|
||||||
url: '/subPages/projectManager/myProject/myProject'
|
url: '/subPages/projectManager/myProject/myProject',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
icon: icon,
|
icon: icon02,
|
||||||
name: '警保风采',
|
name: '整改工单',
|
||||||
url: ''
|
url: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
icon: icon,
|
icon: icon03,
|
||||||
name: '待定',
|
name: '考核排名',
|
||||||
url: ''
|
url: '',
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
icon: icon06,
|
||||||
|
name: '警保风采',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
icon: icon04,
|
||||||
|
name: '法制宣传',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
icon: icon01,
|
||||||
|
name: '整改回单',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const subNavigation = async (url: string) => Taro.navigateTo({ url })
|
const subNavigation = async (url: string) => Taro.navigateTo({ url })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
.mine {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.mine-container {
|
||||||
|
height: 320rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-image: url('../../../assets/images/banner.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 45rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.contacts {
|
||||||
|
height: 75rpx;
|
||||||
|
width: 75rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: solid 1px gray;
|
||||||
|
.image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tips-text {
|
||||||
|
display: flex;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 50rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.exit {
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: solid 0.5px #ebebf7;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: #7d7d7d;
|
||||||
|
.exitItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
.exitItemIndex {
|
||||||
|
height: 40rpx;
|
||||||
|
width: 40rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
line-height: 48rpx;
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.microscope {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 2px #ccc;
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
border-bottom: white;
|
||||||
|
border-left: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,80 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view class="mine">
|
||||||
项目经理我的
|
<view class="mine-container" >
|
||||||
|
<view class="contacts">
|
||||||
|
<image src="@/assets/logo/avatar1.png" mode="scaleToFill" class="image" />
|
||||||
|
</view>
|
||||||
|
<view class="tips-text">
|
||||||
|
<view style="font-size: 15px;">名字</view>
|
||||||
|
<view style="font-size: 12px;">
|
||||||
|
<text style="margin-right: 5px">保安部门 </text>
|
||||||
|
<text>未选择单位</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 用户信息 -->
|
||||||
|
<view class="userIndex">
|
||||||
|
<view class="exit" v-for="item in datalist" :key="item.value" @click="addExit(item.value)">
|
||||||
|
<view class="exitItem">
|
||||||
|
<!-- <view class="exitItemIndex">-->
|
||||||
|
<!-- <image :src="item.url" mode="scaleToFill" class="image" />-->
|
||||||
|
<!-- </view>-->
|
||||||
|
<text style="margin-left: 30rpx;font-size: 12px;">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<view style="margin-right: 40rpx">
|
||||||
|
<text class="microscope"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 退出弹框-->
|
||||||
|
<nut-dialog
|
||||||
|
content="是否退出登录?"
|
||||||
|
v-model:visible="visible" @cancel="visible = false" @ok="onOk"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import './index.scss'
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {useUserStore} from "@/store/userStore";
|
||||||
|
import {useTabBarStore} from "@/store/tabBarStore"
|
||||||
|
import Taro from "@tarojs/taro";
|
||||||
|
|
||||||
|
const {setSelected} = useTabBarStore()
|
||||||
|
const {resetUserInfo} = useUserStore()
|
||||||
|
const visible = ref<boolean>(false)
|
||||||
|
const datalist = ref([
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: '小程序简介',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
name: '退出登录',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
name: '修改用户信息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
name: '意见收集',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const addExit = (index:number)=>{
|
||||||
|
switch (index) {
|
||||||
|
case 1:
|
||||||
|
visible.value = true
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const onOk = ()=>{
|
||||||
|
resetUserInfo()
|
||||||
|
setSelected(0)
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: "/pages/login/login",
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -33,13 +33,7 @@
|
||||||
</nut-radio>
|
</nut-radio>
|
||||||
</nut-radio-group>
|
</nut-radio-group>
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
<nut-form-item label="手机号:">
|
|
||||||
<nut-input
|
|
||||||
v-model="formData.telephone"
|
|
||||||
placeholder="请输入手机号码"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</nut-form-item>
|
|
||||||
<nut-form-item label="行政区划:" prop="name">
|
<nut-form-item label="行政区划:" prop="name">
|
||||||
<view @click="visible = true" style="color: #808080">
|
<view @click="visible = true" style="color: #808080">
|
||||||
{{ streetCommunitySmallCommunityLabel || "请选择行政区划" }}
|
{{ streetCommunitySmallCommunityLabel || "请选择行政区划" }}
|
||||||
|
@ -55,8 +49,9 @@
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
v-model="TreeValue"
|
v-model="TreeValue"
|
||||||
title="选择地址"
|
title="选择地址"
|
||||||
:options="TreeData"
|
|
||||||
@change="change"
|
@change="change"
|
||||||
|
lazy
|
||||||
|
:lazy-load="lazyLoad"
|
||||||
text-key="label"
|
text-key="label"
|
||||||
></nut-cascader>
|
></nut-cascader>
|
||||||
<nut-popup v-model:visible="show" position="bottom">
|
<nut-popup v-model:visible="show" position="bottom">
|
||||||
|
@ -95,18 +90,28 @@ const formData = ref<RegisterParams>({
|
||||||
});
|
});
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
|
|
||||||
const TreeValue = ref<Record<string, any>[]>([])
|
const TreeValue = ref<Record<string, any>[]>([])
|
||||||
const TreeData = ref(['']);
|
// const TreeData = ref([]);
|
||||||
|
|
||||||
const streetCommunitySmallCommunityLabel = ref<string>("");
|
const streetCommunitySmallCommunityLabel = ref<string>("");
|
||||||
const getAdministrativeDivisionTree = async () => {
|
const getAdministrativeDivisionTree = async (value:string) => {
|
||||||
const resp = await api.get<TreeNodeVo<string>[]>('/common/administrativeDivisionTree')
|
const resp = await api.get<TreeNodeVo<string>[]>('/common/administrativeDivisionByParentCode',{parentCode:value})
|
||||||
TreeData.value = resp.data as any
|
return resp.data as any
|
||||||
console.log(resp.data)
|
|
||||||
}
|
}
|
||||||
const change = (value: string, pathNodes: Record<string, any>[]) => {
|
|
||||||
|
|
||||||
|
const change = async (value: string, pathNodes: Record<string, any>[]) => {
|
||||||
streetCommunitySmallCommunityLabel.value = pathNodes.map((e) => e.text).join(",");
|
streetCommunitySmallCommunityLabel.value = pathNodes.map((e) => e.text).join(",");
|
||||||
TreeValue.value = value as any
|
TreeValue.value = value as any
|
||||||
}
|
}
|
||||||
|
const lazyLoad = async (node:any, resolve:any)=>{
|
||||||
|
if (node.root) {
|
||||||
|
await resolve(getAdministrativeDivisionTree ('0'))
|
||||||
|
} else {
|
||||||
|
await resolve(getAdministrativeDivisionTree (node.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
const columns = ref([])
|
const columns = ref([])
|
||||||
const unitsList = async () => {
|
const unitsList = async () => {
|
||||||
if (streetCommunitySmallCommunityLabel.value !== '') {
|
if (streetCommunitySmallCommunityLabel.value !== '') {
|
||||||
|
@ -126,7 +131,7 @@ const unitsList = async () => {
|
||||||
|
|
||||||
|
|
||||||
const selectedLabel = ref('')
|
const selectedLabel = ref('')
|
||||||
const confirm = ({selectedOptions, selectedValue}) => {
|
const confirm = ({selectedOptions}) => {
|
||||||
Object.keys(selectedOptions).forEach((e) => {
|
Object.keys(selectedOptions).forEach((e) => {
|
||||||
selectedLabel.value = selectedOptions[e].label
|
selectedLabel.value = selectedOptions[e].label
|
||||||
formData.value.unitId = selectedOptions[e].value
|
formData.value.unitId = selectedOptions[e].value
|
||||||
|
@ -136,7 +141,7 @@ const confirm = ({selectedOptions, selectedValue}) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 身份
|
// 身份
|
||||||
watch(() => formData.value.identity, (value) => {
|
watch(() => formData.value.identity, () => {
|
||||||
formData.value.unitId = ''
|
formData.value.unitId = ''
|
||||||
selectedLabel.value = ''
|
selectedLabel.value = ''
|
||||||
})
|
})
|
||||||
|
@ -155,7 +160,7 @@ const register = async () => {
|
||||||
identity: formData.value.identity,
|
identity: formData.value.identity,
|
||||||
unitId: formData.value.unitId
|
unitId: formData.value.unitId
|
||||||
}
|
}
|
||||||
const resp = await api.post<string>('/miniProgramUser/register', miniProgramUserRegisterParams, {loading: true})
|
const resp = await api.post<string>('/mp/user/register', miniProgramUserRegisterParams, {loading: true})
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: "注册成功",
|
title: "注册成功",
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
|
@ -165,7 +170,7 @@ const register = async () => {
|
||||||
await Taro.setStorage({
|
await Taro.setStorage({
|
||||||
key: "token",
|
key: "token",
|
||||||
data: resp.data,
|
data: resp.data,
|
||||||
success(res) {
|
success() {
|
||||||
Taro.navigateTo({
|
Taro.navigateTo({
|
||||||
url: '/pages/login/login'
|
url: '/pages/login/login'
|
||||||
})
|
})
|
||||||
|
@ -209,10 +214,10 @@ const onChooseAvatar = (e) => {
|
||||||
formData.value.avatar = avatarUrl
|
formData.value.avatar = avatarUrl
|
||||||
}
|
}
|
||||||
// 获取昵称
|
// 获取昵称
|
||||||
const getNickname = (e) => {
|
// const getNickname = (e) => {
|
||||||
formData.value.name = e.detail.value
|
// formData.value.name = e.detail.value
|
||||||
console.log(formData.value.name)
|
// console.log(formData.value.name)
|
||||||
}
|
// }
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getAdministrativeDivisionTree()
|
await getAdministrativeDivisionTree()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default {
|
||||||
|
"component": true
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
.uiwu-flex-align {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiwu-flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiwu-flex-space {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiwu-picker-search {
|
||||||
|
position: absolute;
|
||||||
|
height: 1031rpx;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: url('../assets/images/popuptiobg.png') no-repeat 0 0 #fff;
|
||||||
|
background-size: 100% auto;
|
||||||
|
border-radius: 30rpx 30rpx 0 0;
|
||||||
|
|
||||||
|
&-btn {
|
||||||
|
padding: 20rpx 30rpx 40rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
&:nth-child(1) {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
color: #00bbff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 80rpx;
|
||||||
|
background: rgba(#f3f6fd, 0.6);
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin: 0 30rpx;
|
||||||
|
padding-left: 24rpx;
|
||||||
|
padding-right: 10rpx;
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 28rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-view {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 212rpx);
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-group {
|
||||||
|
padding: 0 50rpx 30rpx;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchButton {
|
||||||
|
height: 60rpx;
|
||||||
|
width: 200rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #00bbff;
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view @tap.stop="open">11111</view>
|
||||||
|
<nut-popup v-model:visible="show" position="bottom" round="true">
|
||||||
|
<view style="height: 1031rpx">
|
||||||
|
<view class="uiwu-picker-search">
|
||||||
|
<view class="uiwu-picker-search-btn uiwu-flex uiwu-flex-space">
|
||||||
|
<text @tap.stop="show = false">取消</text>
|
||||||
|
<text @tap.stop="determine">确定</text>
|
||||||
|
</view>
|
||||||
|
<view class="uiwu-picker-search-input uiwu-flex uiwu-flex-align">
|
||||||
|
<input v-model="inputText.value" type="text" :placeholder="placeholder" confirm-type="search" @confirm="confirm_" />
|
||||||
|
<view @click.stop="confirm" class="searchButton">搜索</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="scroll-view" scroll-y>
|
||||||
|
<!-- <radio-group class="radio-group" @change="change">
|
||||||
|
<view class="radio-group-item uiwu-flex uiwu-flex-space" v-for="(item, index) in listData.value" :key="index">
|
||||||
|
<text>{{ item.bank_name }}</text>
|
||||||
|
<radio :value="item.bank_name" color="#687CFF" />
|
||||||
|
</view>
|
||||||
|
</radio-group> -->
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</nut-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import './picker-search.scss'
|
||||||
|
import { ref, expose } from 'vue'
|
||||||
|
// import { searchBankName } from '@/api/app'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '请输入银行名称',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// 定义响应式变量
|
||||||
|
const show = ref(true)
|
||||||
|
const listData = ref([])
|
||||||
|
const currentBankName = ref('')
|
||||||
|
const inputText = ref('')
|
||||||
|
|
||||||
|
// 搜索方法
|
||||||
|
const confirm = () => {
|
||||||
|
// searchBankName({ bank_name: inputText.value.trim() }).then((res) => {
|
||||||
|
// console.log('searchBankName', res)
|
||||||
|
// listData.value = res.data
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入确认方法
|
||||||
|
const confirm_ = ({ detail: { value } }) => {
|
||||||
|
console.log('confirm', value)
|
||||||
|
// searchBankName({ bank_name: value.trim() }).then((res) => {
|
||||||
|
// console.log('searchBankName', res)
|
||||||
|
// listData.value = res.data
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单选框切换方法
|
||||||
|
const change = ({ detail: { value } }) => {
|
||||||
|
console.log('change', value)
|
||||||
|
currentBankName.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定方法
|
||||||
|
const determine = () => {
|
||||||
|
if (currentBankName.value.trim() === '') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请选择银行',
|
||||||
|
duration: 1500,
|
||||||
|
icon: 'error',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 触发父组件的事件,传递选择的银行名称
|
||||||
|
emit('change', currentBankName.value.trim())
|
||||||
|
show.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开弹窗
|
||||||
|
const open = () => {
|
||||||
|
show.value = true
|
||||||
|
}
|
||||||
|
// expose({ open })
|
||||||
|
</script>
|
|
@ -35,6 +35,9 @@ class CustomRequest {
|
||||||
Taro.showLoading({
|
Taro.showLoading({
|
||||||
title: '请求中...',
|
title: '请求中...',
|
||||||
}).then()
|
}).then()
|
||||||
|
// Taro.showLoading({
|
||||||
|
// title: '请求中...',
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
Taro.request<JsonResult<T>, object>({
|
Taro.request<JsonResult<T>, object>({
|
||||||
url: this.BASE_API + url,
|
url: this.BASE_API + url,
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useDailyStore = defineStore('daily', {
|
||||||
|
state: () => ({
|
||||||
|
userdailyinspection: [],
|
||||||
|
base64_1: '',
|
||||||
|
base64_2: '',
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
dailyinspectionList(data) {
|
||||||
|
this.userdailyinspection = [...data]
|
||||||
|
},
|
||||||
|
change_base64_1(data) {
|
||||||
|
this.base64_1 = data
|
||||||
|
},
|
||||||
|
change_base64_2(data) {
|
||||||
|
this.base64_2 = data
|
||||||
|
},
|
||||||
|
clearSignData() {
|
||||||
|
this.base64_1 = ''
|
||||||
|
this.base64_2 = ''
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
getdailyinspection(state) {
|
||||||
|
return state.userdailyinspection
|
||||||
|
},
|
||||||
|
get_base64_1(state) {
|
||||||
|
return state.base64_1
|
||||||
|
},
|
||||||
|
get_base64_2(state) {
|
||||||
|
return state.base64_2
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,149 @@
|
||||||
|
page {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker {
|
||||||
|
padding: 30rpx 30rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exit {
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: solid 0.5px #ebebf7;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.exitItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconoscope {
|
||||||
|
z-index: 9999;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 2px #c2c2c2;
|
||||||
|
margin-left: 10px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
border-bottom: white;
|
||||||
|
border-left: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sigh_btns {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
transform-origin: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.sigh_btns_noRotate {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.input_width {
|
||||||
|
width: 400rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.uiwu-flex-align {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiwu-flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiwu-flex-space {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiwu-picker-search {
|
||||||
|
position: absolute;
|
||||||
|
height: 1031rpx;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: url('../../../assets/images/popuptiobg.png') no-repeat 0 0 #fff;
|
||||||
|
background-size: 100% auto;
|
||||||
|
border-radius: 30rpx 30rpx 0 0;
|
||||||
|
|
||||||
|
&-btn {
|
||||||
|
padding: 20rpx 30rpx 40rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
&:nth-child(1) {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
color: rgb(73, 143, 242);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 80rpx;
|
||||||
|
background: rgba(#f3f6fd, 0.6);
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin: 0 30rpx;
|
||||||
|
padding-left: 24rpx;
|
||||||
|
padding-right: 10rpx;
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 28rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-view {
|
||||||
|
width: 100%;
|
||||||
|
height: 800rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-group {
|
||||||
|
padding: 0 50rpx 30rpx;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchButton {
|
||||||
|
height: 60rpx;
|
||||||
|
width: 200rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgb(73, 143, 242);
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '监督考核',
|
||||||
|
})
|
|
@ -0,0 +1,404 @@
|
||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<nut-form labelWidth="320rpx" labelAlign="left" @click.stop="openSearch">
|
||||||
|
<nut-form-item label="考核单位:">
|
||||||
|
<view class="input_width">
|
||||||
|
<input style="width: 300rpx" disabled="true" v-model="enterprisesName" placeholder="请选择考核单位:" />
|
||||||
|
<IconFont name="arrow-down"></IconFont>
|
||||||
|
</view>
|
||||||
|
</nut-form-item>
|
||||||
|
</nut-form>
|
||||||
|
|
||||||
|
<!-- <picker mode="selector" :range="selector" rangeKey="label" @change="onChange">
|
||||||
|
<view class="picker">
|
||||||
|
考核单位:
|
||||||
|
<view style="display: flex; align-items: center">
|
||||||
|
<view v-if="selectorChecked.length === 0" style="color: #606266">请选择考核单位:</view>
|
||||||
|
<view> {{ selectorChecked }}</view>
|
||||||
|
<IconFont name="arrow-right"></IconFont>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</picker> -->
|
||||||
|
|
||||||
|
<picker v-if="(selectorType?.length ?? 0) > 0" mode="selector" :range="selectorType" rangeKey="label" @change="onChangeType">
|
||||||
|
<view class="picker">
|
||||||
|
当前考核项目:
|
||||||
|
<view style="display: flex; align-items: center">
|
||||||
|
<view v-if="selectorCheckedType.length === 0" style="color: #606266">请选择考核项目</view>
|
||||||
|
<view> {{ selectorCheckedType }}</view>
|
||||||
|
<IconFont name="arrow-right"></IconFont>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
|
||||||
|
<view class="exit" v-for="item in starRating" :key="item.snowFlakeId" @click="Onrating(item.name, item.snowFlakeId)">
|
||||||
|
<view class="exitItem">
|
||||||
|
<text style="margin-left: 30rpx; font-size: 16px">
|
||||||
|
<text>{{ item.name }}({{ item?.totalScore }}分) </text>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view style="margin-right: 30rpx; display: flex; align-items: center">
|
||||||
|
<view v-if="item.currentScore > 0" style="color: #ff0000"> -{{ item?.currentScore }}</view>
|
||||||
|
<IconFont name="arrow-right"></IconFont>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<nut-form labelWidth="320rpx" labelAlign="left">
|
||||||
|
<nut-form-item label="备注">
|
||||||
|
<nut-input v-model="_form.remark" placeholder="请输入备注" type="text" />
|
||||||
|
</nut-form-item>
|
||||||
|
|
||||||
|
<nut-form-item label="考核人员签名:">
|
||||||
|
<navigator :url="`/subPages/select/signature/signature?index=${1}&name=考核人员签名`" hover-class="navigator-hover">
|
||||||
|
<nut-button style="height: 50rpx" shape="square" type="info">考核人员签字</nut-button>
|
||||||
|
</navigator>
|
||||||
|
</nut-form-item>
|
||||||
|
<view style="display: flex; justify-content: center">
|
||||||
|
<image v-if="_form.assessmentUserSignature" :src="_form.assessmentUserSignature" mode="aspectFit" style="height: 300rpx"></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<nut-form-item label="被考评学校签名:">
|
||||||
|
<navigator :url="`/subPages/select/signature/signature?index=${2}&name=被考评学校签名`" hover-class="navigator-hover">
|
||||||
|
<nut-button style="height: 50rpx" shape="square" type="info">被考评学校负责人</nut-button>
|
||||||
|
</navigator>
|
||||||
|
</nut-form-item>
|
||||||
|
<view style="display: flex; justify-content: center">
|
||||||
|
<image v-if="_form.byAssessmentEnterprisesUnitUserSignature" :src="_form.byAssessmentEnterprisesUnitUserSignature" mode="heightFix" style="height: 300rpx"></image>
|
||||||
|
</view>
|
||||||
|
</nut-form>
|
||||||
|
</view>
|
||||||
|
<view style="height: 150rpx"></view>
|
||||||
|
<view style="display: flex; width: 100%; justify-content: center; position: fixed; bottom: 50rpx">
|
||||||
|
<nut-button :loading="isLoading" shape="round" type="info" @click="onSubmit" style="height: 80rpx; width: 702rpx; margin: 10rpx auto">确认提交</nut-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<nut-popup v-model:visible="show" position="bottom" :round="true">
|
||||||
|
<view style="height: 1031rpx">
|
||||||
|
<view class="uiwu-picker-search">
|
||||||
|
<view class="uiwu-picker-search-btn uiwu-flex uiwu-flex-space">
|
||||||
|
<text @tap.stop="show = false">取消</text>
|
||||||
|
<text @tap.stop="determine">确定</text>
|
||||||
|
</view>
|
||||||
|
<view class="uiwu-picker-search-input uiwu-flex uiwu-flex-align">
|
||||||
|
<input v-model="inputText" type="text" placeholder="请输入单位名称" confirm-type="search" @confirm="confirm_" />
|
||||||
|
<view @click.stop="confirm" class="searchButton">搜索</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="scroll-view" :scroll-y="true">
|
||||||
|
<!-- <radio-group class="radio-group" @change="radioChange">
|
||||||
|
<view class="radio-group-item uiwu-flex uiwu-flex-space" v-for="(item, index) in selector" :key="index">
|
||||||
|
<text>{{ item.label }}</text>
|
||||||
|
<radio :value="item.value" color="#687CFF" />
|
||||||
|
</view>
|
||||||
|
</radio-group> -->
|
||||||
|
<nut-radio-group v-if="(selectorCopy?.length ?? 0) > 0" style="margin-left: 30rpx" v-model="selectedID">
|
||||||
|
<nut-radio icon-size="20" v-for="(item, index) in selectorCopy" :key="index" :label="item.value"> {{ item.label }}</nut-radio>
|
||||||
|
<view style="height: 40rpx"></view>
|
||||||
|
</nut-radio-group>
|
||||||
|
<nut-empty v-else description="暂无单位"></nut-empty>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</nut-popup>
|
||||||
|
</view>
|
||||||
|
<!-- <picker-search ref="picker_search" @change="changeSearch" /> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// import PickerSearch from '@/components/PickerSearch.vue'
|
||||||
|
// import picker-search from
|
||||||
|
import { IconFont } from '@nutui/icons-vue-taro'
|
||||||
|
import Taro, { useLoad, useUnload } from '@tarojs/taro'
|
||||||
|
import './dailyInspection.scss'
|
||||||
|
import { ref, computed, reactive, watch } from 'vue'
|
||||||
|
import api from '@/request/index'
|
||||||
|
import { useDailyStore } from '@/store/daily'
|
||||||
|
|
||||||
|
// const picker_search = ref()
|
||||||
|
const starRating = ref<any[]>([])
|
||||||
|
const store = useDailyStore()
|
||||||
|
const daily = computed(() => store.getdailyinspection)
|
||||||
|
const base64_1 = computed(() => store.get_base64_1)
|
||||||
|
const base64_2 = computed(() => store.get_base64_2)
|
||||||
|
|
||||||
|
const currentCkProjectId = ref('')
|
||||||
|
const submitData = ref<Item[]>([])
|
||||||
|
const enterprisesName = ref('')
|
||||||
|
const _form = reactive({
|
||||||
|
enterprisesUnitId: '', //企事业单位id
|
||||||
|
ckProjectId: '', //考核项目
|
||||||
|
assessmentUserSignature: '', //考核人员签字
|
||||||
|
byAssessmentEnterprisesUnitUserSignature: '', // 被考核单位人员签字
|
||||||
|
remark: '', //考核备注
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
[daily, base64_1, base64_2],
|
||||||
|
([newDaily, newBase64_1, newBase64_2]) => {
|
||||||
|
_form.assessmentUserSignature = newBase64_1
|
||||||
|
_form.byAssessmentEnterprisesUnitUserSignature = newBase64_2
|
||||||
|
|
||||||
|
if (newDaily.length > 0) {
|
||||||
|
starRating.value = newDaily
|
||||||
|
}
|
||||||
|
submitData.value = newDaily
|
||||||
|
// console.log('watch_______________', _form, submitData.value)
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
useLoad(async () => {
|
||||||
|
await getUnitEnterprisesUnitList()
|
||||||
|
})
|
||||||
|
|
||||||
|
const Onrating = function (name: string, snowFlakeId: string) {
|
||||||
|
let index = starRating.value.findIndex((item) => item.snowFlakeId === snowFlakeId)
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/subPages/select/dailyLife/dailyLife?name=${name}&index=${index}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @assessmentCriteriaRulesByCkProjectId 获取考核规则
|
||||||
|
*/
|
||||||
|
|
||||||
|
const assessmentCriteriaRulesByCkProjectId = async function (ckProjectId) {
|
||||||
|
// Taro.showLoading({
|
||||||
|
// title: '加载中...',
|
||||||
|
// mask: true,
|
||||||
|
// })
|
||||||
|
const res = await api.get<StarRating[]>(`/mp/sa/assessmentCriteriaRulesByCkProjectId`, { ckProjectId })
|
||||||
|
|
||||||
|
res.data?.forEach((item) => {
|
||||||
|
item.currentScore = 0
|
||||||
|
|
||||||
|
item.itemList.forEach((element: ItemList) => {
|
||||||
|
element.standardList.forEach((ele) => {
|
||||||
|
ele.isSelected = false
|
||||||
|
})
|
||||||
|
element.standardList.unshift({
|
||||||
|
ckItemId: 'null',
|
||||||
|
deductionPoints: 0,
|
||||||
|
name: '达标',
|
||||||
|
snowFlakeId: 'null',
|
||||||
|
isSelected: true,
|
||||||
|
})
|
||||||
|
element.selectedID = element.standardList[0].snowFlakeId
|
||||||
|
element.selected_points = 0 // 默认达标 默认扣 0 分
|
||||||
|
// 多选
|
||||||
|
if (element.type.value === 'multiple') {
|
||||||
|
element.selectedGroup = [element.selectedID]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
starRating.value = res.data ?? []
|
||||||
|
// console.log('starRating.value______________________________', starRating.value)
|
||||||
|
|
||||||
|
store.dailyinspectionList(starRating.value)
|
||||||
|
// Taro.hideLoading()
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @ckProjectListByType 根据类型获取考核标准列表
|
||||||
|
*/
|
||||||
|
|
||||||
|
const selectorCheckedType = ref<string>('')
|
||||||
|
const selectorType = ref<CkProjectListByType[]>()
|
||||||
|
const ckProjectListByType = async function (type) {
|
||||||
|
const res = await api.get<CkProjectListByType[]>(`/mp/sa/ckProjectListByType`, { type })
|
||||||
|
console.log(res.data)
|
||||||
|
|
||||||
|
if (res.data?.length === 0) {
|
||||||
|
let timeID = setTimeout(() => {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '该单位下面没有考核标准',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000,
|
||||||
|
})
|
||||||
|
clearTimeout(timeID)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
selectorType.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeType = function (e: any) {
|
||||||
|
let index = Number(e.detail.value)
|
||||||
|
selectorCheckedType.value = selectorType.value?.[index].label as string
|
||||||
|
currentCkProjectId.value = selectorType.value?.[index].value as string
|
||||||
|
assessmentCriteriaRulesByCkProjectId(currentCkProjectId.value)
|
||||||
|
_form.ckProjectId = selectorType.value?.[index].value as string
|
||||||
|
}
|
||||||
|
|
||||||
|
const selector = ref<UnitEnterprisesUnitList[]>()
|
||||||
|
const selectorCopy = ref<UnitEnterprisesUnitList[]>()
|
||||||
|
// const selectorChecked = ref<string>('')
|
||||||
|
// const onChange = function (e: any) {
|
||||||
|
// try {
|
||||||
|
// let index = Number(e.detail.value)
|
||||||
|
// selectorChecked.value = selector.value?.[index].label as string
|
||||||
|
// let type = selector.value?.[index].extData.type.value
|
||||||
|
// ckProjectListByType(type)
|
||||||
|
// _form.enterprisesUnitId = selector.value?.[index].value as string
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log('🚀 ~ onChange ~ error:', error)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const getUnitEnterprisesUnitList = async function () {
|
||||||
|
const res = await api.get<UnitEnterprisesUnitList[]>(`/policeIndex/getUnitEnterprisesUnitList`)
|
||||||
|
|
||||||
|
selector.value = res.data
|
||||||
|
selectorCopy.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
const _showToast = function (title) {
|
||||||
|
Taro.showToast({
|
||||||
|
title,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 1500,
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @onSubmit 提交
|
||||||
|
* @assessmentRecordDetails 选择后的数据用于提交
|
||||||
|
* @clearData 清空数据
|
||||||
|
*/
|
||||||
|
|
||||||
|
const assessmentRecordDetails = ref<any[]>([])
|
||||||
|
const clearData = function () {
|
||||||
|
store.clearSignData()
|
||||||
|
store.dailyinspectionList([])
|
||||||
|
assessmentRecordDetails.value = []
|
||||||
|
_form.assessmentUserSignature = ''
|
||||||
|
_form.byAssessmentEnterprisesUnitUserSignature = ''
|
||||||
|
_form.remark = ''
|
||||||
|
assessmentCriteriaRulesByCkProjectId(currentCkProjectId.value) //重新获取数据
|
||||||
|
}
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const onSubmit = async function () {
|
||||||
|
if (_form.enterprisesUnitId === '') {
|
||||||
|
_showToast('请选择企事业单位')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (_form.ckProjectId === '') {
|
||||||
|
_showToast('请选择考核项目')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (_form.assessmentUserSignature === '') {
|
||||||
|
_showToast('请考核人员签字')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (_form.byAssessmentEnterprisesUnitUserSignature === '') {
|
||||||
|
_showToast('请被考核单位人员签字')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
submitData.value.forEach((element: StarRating) => {
|
||||||
|
element?.itemList.forEach((item: ItemList) => {
|
||||||
|
item.standardList.forEach((ele: StandardList) => {
|
||||||
|
if (ele.snowFlakeId === item.selectedID && !item.hasOwnProperty('selectedGroup') && item.selectedID != 'null') {
|
||||||
|
assessmentRecordDetails.value.push({
|
||||||
|
ckGroupId: element.snowFlakeId, //选项的雪花Id
|
||||||
|
ckItemId: ele.ckItemId, //已选择的ID
|
||||||
|
ckStandardId: item.selectedID, //已选择的雪花ID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (item.hasOwnProperty('selectedGroup')) {
|
||||||
|
item.selectedGroup.forEach((selectedItem) => {
|
||||||
|
item.standardList.forEach((standard_Element) => {
|
||||||
|
if (selectedItem != 'null' && selectedItem === standard_Element.snowFlakeId) {
|
||||||
|
assessmentRecordDetails.value.push({
|
||||||
|
ckGroupId: element.snowFlakeId, //选项的雪花Id
|
||||||
|
ckItemId: standard_Element.ckItemId, //已选择的ID
|
||||||
|
ckStandardId: selectedItem, //已选择的雪花ID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const assessmentRecordParams = {
|
||||||
|
assessmentRecordDetails: [] as any[],
|
||||||
|
}
|
||||||
|
Object.assign(assessmentRecordParams, _form)
|
||||||
|
assessmentRecordParams.assessmentRecordDetails = [...assessmentRecordDetails.value]
|
||||||
|
const result = await api.post('/mp/sa/submitAssessmentRecord', assessmentRecordParams)
|
||||||
|
|
||||||
|
clearData() //清空数据
|
||||||
|
if (result.code === 200) {
|
||||||
|
isLoading.value = false
|
||||||
|
|
||||||
|
let timeID = setTimeout(() => {
|
||||||
|
Taro.showToast({
|
||||||
|
title: result.message,
|
||||||
|
icon: 'success',
|
||||||
|
duration: 2000,
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
clearTimeout(timeID)
|
||||||
|
}, 500)
|
||||||
|
} else {
|
||||||
|
_showToast(result.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useUnload(() => {
|
||||||
|
store.clearSignData()
|
||||||
|
store.dailyinspectionList([])
|
||||||
|
assessmentRecordDetails.value = []
|
||||||
|
_form.assessmentUserSignature = ''
|
||||||
|
_form.byAssessmentEnterprisesUnitUserSignature = ''
|
||||||
|
_form.remark = ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const show = ref(false)
|
||||||
|
const inputText = ref('')
|
||||||
|
const selectedID = ref('')
|
||||||
|
|
||||||
|
const openSearch = () => {
|
||||||
|
show.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const fuzzySearch = function (query) {
|
||||||
|
selectorCopy.value = selector.value?.filter((item) => item.label.includes(query))
|
||||||
|
}
|
||||||
|
const confirm = () => {
|
||||||
|
console.log(inputText.value)
|
||||||
|
if (inputText.value.trim() === '') {
|
||||||
|
selectorCopy.value = selector.value
|
||||||
|
} else {
|
||||||
|
fuzzySearch(inputText.value.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const confirm_ = ({ detail: { value } }) => {
|
||||||
|
console.log('confirm', value)
|
||||||
|
if (inputText.value.trim() === '') {
|
||||||
|
selectorCopy.value = selector.value
|
||||||
|
} else {
|
||||||
|
fuzzySearch(inputText.value.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const determine = () => {
|
||||||
|
console.log(selectedID.value)
|
||||||
|
if (selectedID.value === '' && (selector.value?.length as number) > 0) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请选择单位',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 1500,
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let index: number = selector.value?.findIndex((item) => item.value === selectedID.value) as number
|
||||||
|
_form.enterprisesUnitId = selectedID.value
|
||||||
|
let type = selector.value?.[index].extData.type.value
|
||||||
|
enterprisesName.value = selector.value?.[index].label as string
|
||||||
|
show.value = false
|
||||||
|
ckProjectListByType(type)
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -17,16 +17,13 @@ page {
|
||||||
}
|
}
|
||||||
|
|
||||||
.project {
|
.project {
|
||||||
display: flex;
|
//display: flex;
|
||||||
justify-content: space-between;
|
//justify-content: space-between;
|
||||||
flex-flow: wrap;
|
//flex-flow: wrap;
|
||||||
text-align: center;
|
//text-align: center;
|
||||||
|
|
||||||
view {
|
view {
|
||||||
width: 45%;
|
width: 100%;
|
||||||
height: 100rpx;
|
|
||||||
border: 1px solid #cccccc;
|
|
||||||
line-height: 100rpx;
|
|
||||||
margin: 8px 0 8px 0;
|
margin: 8px 0 8px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="myProject">
|
<view class="myProject">
|
||||||
<view class="myProjectItem" v-for="(item,index) in myProjectList" :key="index">
|
<view v-if="number !== 0" class="myProjectItem" v-for="(item, index) in myProjectList" :key="index">
|
||||||
<view style="display: flex; justify-content: space-between">
|
<view style="display: flex; justify-content: space-between">
|
||||||
<text>{{ item?.name }}</text>
|
<text>{{ item?.name }}</text>
|
||||||
<!--<text>进行中</text>-->
|
<text>单位类型:{{ item?.type?.label }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="myProjectIndex">地址:
|
<view class="myProjectIndex"
|
||||||
|
>地址:
|
||||||
<text>{{ item?.provinceName }}{{ item.cityName }}{{ item.districtsName }}{{ item.streetName }}</text>
|
<text>{{ item?.provinceName }}{{ item.cityName }}{{ item.districtsName }}{{ item.streetName }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view style="display: flex; justify-content: space-between">
|
<view style="display: flex; justify-content: space-between">
|
||||||
|
@ -13,26 +14,41 @@
|
||||||
<text>电话:{{ item?.contactPersonInfo.telephone }}</text>
|
<text>电话:{{ item?.contactPersonInfo.telephone }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="project">
|
<view class="project">
|
||||||
<view @click="projectClick(item?.name,serviceProject)" v-for="(serviceProject,index) in item.serviceProjectList"
|
<view @click="projectClick(item?.name, serviceProject)" v-for="(serviceProject, index) in item.serviceProjectList" :key="index">
|
||||||
:key="index">
|
<view style="border: 1px solid #cccccc; color: #9b9b9f">
|
||||||
{{ serviceProject.name }}
|
<view style="display: flex; justify-content: space-between">
|
||||||
|
<text>项目名称:{{ serviceProject.name }}</text>
|
||||||
|
<text>项目类型:{{ serviceProject.type?.label }}</text>
|
||||||
|
</view>
|
||||||
|
<view style="display: flex; justify-content: space-between">
|
||||||
|
<text>项目负责人:{{ serviceProject.projectManagerMiniProgramUserInfo?.name ? serviceProject.projectManagerMiniProgramUserInfo?.name : '无分配项目经理' }}</text>
|
||||||
|
</view>
|
||||||
|
<view>责任单位:{{ serviceProject.securityUnitName }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view v-else class="myProject">
|
||||||
|
<nut-empty image="empty" description="暂无项目">
|
||||||
|
<div style="margin-top: 10px"></div>
|
||||||
|
</nut-empty>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from "@/request/index";
|
import api from '@/request/index'
|
||||||
import {onMounted, ref} from "vue";
|
import { onMounted, ref } from 'vue'
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from '@tarojs/taro'
|
||||||
import './myEnterprisesUnit.scss'
|
import './myEnterprisesUnit.scss'
|
||||||
import {MyProjectList, ServiceProjectList} from "@/types/subPages/projectManager/myProject";
|
import { MyProjectList, ServiceProjectList } from '@/types/subPages/projectManager/myProject'
|
||||||
|
|
||||||
const myProjectList = ref<MyProjectList[]>()
|
const myProjectList = ref<MyProjectList[]>()
|
||||||
|
const number = ref(0)
|
||||||
const getMyServiceProject = async () => {
|
const getMyServiceProject = async () => {
|
||||||
const resp = await api.get<MyProjectList[]>(`/policeIndex/getUnitServiceProjectList`)
|
const resp = await api.get<MyProjectList[]>(`/policeIndex/getUnitServiceProjectList`)
|
||||||
myProjectList.value = resp.data
|
myProjectList.value = resp.data
|
||||||
|
number.value = resp.data?.length || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectClick = (enterprisesUnitName: string, serviceProject: ServiceProjectList) => {
|
const projectClick = (enterprisesUnitName: string, serviceProject: ServiceProjectList) => {
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
<!-- <text>进行中</text>-->
|
<!-- <text>进行中</text>-->
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<view style="float: left;width: 50%;" class="content">
|
<view style="float: left; width: 50%" class="content"> 经理名称:{{ serviceProject?.projectManagerMiniProgramUserInfo.name }} </view>
|
||||||
经理名称:{{ serviceProject?.projectManagerMiniProgramUserInfo.name }}
|
|
||||||
</view>
|
|
||||||
<view class="content">手机号:{{ serviceProject?.projectManagerMiniProgramUserInfo.telephone }}</view>
|
<view class="content">手机号:{{ serviceProject?.projectManagerMiniProgramUserInfo.telephone }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -47,9 +45,16 @@
|
||||||
<!--表格-->
|
<!--表格-->
|
||||||
<view class="projectDetailsTableDrop">
|
<view class="projectDetailsTableDrop">
|
||||||
<view style="padding: 0 12px">项目人员</view>
|
<view style="padding: 0 12px">项目人员</view>
|
||||||
<scroll-view :scroll-y="true" style="height: 80%;" @scrolltoupper="upper" @scrolltolower="lower"
|
<scroll-view
|
||||||
:scroll-into-view="toView" :scroll-top="scrollTop" :refresherEnabled="true"
|
:scroll-y="true"
|
||||||
@refresherrefresh="onRefresherRefresh" :refresher-triggered="isRefresher"
|
style="height: 80%"
|
||||||
|
@scrolltoupper="upper"
|
||||||
|
@scrolltolower="lower"
|
||||||
|
:scroll-into-view="toView"
|
||||||
|
:scroll-top="scrollTop"
|
||||||
|
:refresherEnabled="true"
|
||||||
|
@refresherrefresh="onRefresherRefresh"
|
||||||
|
:refresher-triggered="isRefresher"
|
||||||
>
|
>
|
||||||
<view class="projectDetailsTable" v-for="(item, index) in securityUserList" :key="index">
|
<view class="projectDetailsTable" v-for="(item, index) in securityUserList" :key="index">
|
||||||
<view>
|
<view>
|
||||||
|
@ -61,12 +66,12 @@
|
||||||
<text>职位:{{ item.workPost ? item.workPost : '创建者' }}</text>
|
<text>职位:{{ item.workPost ? item.workPost : '创建者' }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view style="display: flex; justify-content: space-between">
|
<view style="display: flex; justify-content: space-between">
|
||||||
<text>保安证件:{{ item.securityNumber ? item.securityNumber : '125241256451' }}</text>
|
<text>保安证件:{{ item.securityNumber ? item.securityNumber : '无' }}</text>
|
||||||
<text>出生年月:{{ dayjs(item.dateOfBirth).format('YYYY-MM-DD') }}</text>
|
<text>出生年月:{{ dayjs(item.dateOfBirth).format('YYYY-MM-DD') }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view style="display: flex; justify-content: space-between">
|
<view style="display: flex; justify-content: space-between">
|
||||||
<text>创建时间:{{ item.createTime }}</text>
|
<text>创建时间:{{ item.createTime }}</text>
|
||||||
<text>身份证:{{ item.idCard }}</text>
|
<text>身份证:{{ item.idCard?.desensitizedValue }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -74,16 +79,15 @@
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Taro, {useLoad} from "@tarojs/taro";
|
import Taro, { useLoad } from '@tarojs/taro'
|
||||||
import './projectDetails.scss'
|
import './projectDetails.scss'
|
||||||
import {ref} from "vue";
|
import { ref } from 'vue'
|
||||||
import api from "@/request/index";
|
import api from '@/request/index'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import {ServiceProjectSecurityUserPagerVo} from "@/types/subPages/projectManager/myProject";
|
import { ServiceProjectSecurityUserPagerVo } from '@/types/subPages/projectManager/myProject'
|
||||||
|
|
||||||
const serviceProject = ref()
|
const serviceProject = ref()
|
||||||
const enterprisesUnitName = ref('')
|
const enterprisesUnitName = ref('')
|
||||||
|
@ -91,11 +95,10 @@ const securityUserList = ref<ServiceProjectSecurityUserPagerVo[]>([])
|
||||||
useLoad(async (options) => {
|
useLoad(async (options) => {
|
||||||
enterprisesUnitName.value = options.enterprisesUnitName
|
enterprisesUnitName.value = options.enterprisesUnitName
|
||||||
serviceProject.value = JSON.parse(options.serviceProject)
|
serviceProject.value = JSON.parse(options.serviceProject)
|
||||||
console.log(serviceProject.value);
|
console.log(serviceProject.value)
|
||||||
await projectDetailsTable()
|
await projectDetailsTable()
|
||||||
})
|
})
|
||||||
const projectDetailsTable = async () => {
|
const projectDetailsTable = async () => {
|
||||||
// if (total.value === projectData.value.length) return
|
|
||||||
Taro.showLoading({
|
Taro.showLoading({
|
||||||
title: '加载中',
|
title: '加载中',
|
||||||
})
|
})
|
||||||
|
@ -105,10 +108,10 @@ const projectDetailsTable = async () => {
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
size: 4,
|
size: 4,
|
||||||
current: current.value
|
current: current.value,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
const resp = await api.post<PagerVo<ServiceProjectSecurityUserPagerVo>>('/mp/user/securityUserPager', queryParams)
|
||||||
const resp = await api.post<PagerVo<ServiceProjectSecurityUserPagerVo>>('/miniProgramUser/securityUserPager', queryParams)
|
|
||||||
securityUserList.value = [...securityUserList.value, ...resp.data!.records]
|
securityUserList.value = [...securityUserList.value, ...resp.data!.records]
|
||||||
total.value = resp.data!.total
|
total.value = resp.data!.total
|
||||||
isRefresher.value = false
|
isRefresher.value = false
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
|
page {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
.myProject {
|
.myProject {
|
||||||
height: 100vh;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #f1f1f1;
|
|
||||||
|
|
||||||
.myProjectItem {
|
.myProjectItem {
|
||||||
//height: 20%;
|
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
@ -18,16 +16,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.project {
|
.project {
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-flow: wrap;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
view {
|
view {
|
||||||
width: 45%;
|
width: 100%;
|
||||||
height: 100rpx;
|
|
||||||
border: 1px solid #cccccc;
|
|
||||||
line-height: 100rpx;
|
|
||||||
margin: 8px 0 8px 0;
|
margin: 8px 0 8px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<view class="myProjectItem" v-for="(item,index) in myProjectList" :key="index">
|
<view class="myProjectItem" v-for="(item,index) in myProjectList" :key="index">
|
||||||
<view style="display: flex;justify-content: space-between">
|
<view style="display: flex;justify-content: space-between">
|
||||||
<text>{{ item?.name }}</text>
|
<text>{{ item?.name }}</text>
|
||||||
|
<text>单位类型:{{ item?.type.label }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="myProjectIndex">地址:
|
<view class="myProjectIndex">地址:
|
||||||
<text>{{ item?.provinceName }}{{ item.cityName }}{{ item.districtsName }}{{ item.streetName }}</text>
|
<text>{{ item?.provinceName }}{{ item.cityName }}{{ item.districtsName }}{{ item.streetName }}</text>
|
||||||
|
@ -13,9 +14,17 @@
|
||||||
<text>电话:{{ item?.contactPersonInfo.telephone }}</text>
|
<text>电话:{{ item?.contactPersonInfo.telephone }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="project">
|
<view class="project">
|
||||||
<view @click="projectClick(item.name,serviceProject)"
|
<view @click="projectClick(item?.name, serviceProject)" v-for="(serviceProject, index) in item.serviceProjectList" :key="index">
|
||||||
v-for="(serviceProject,index) in item.serviceProjectList" :key="index">
|
<view style="border: 1px solid #cccccc;color: #9b9b9f">
|
||||||
{{ serviceProject.name }}
|
<view style="display: flex; justify-content: space-between">
|
||||||
|
<text>项目名称:{{serviceProject.name}}</text>
|
||||||
|
<text>项目类型:{{serviceProject.type.label}}</text>
|
||||||
|
</view>
|
||||||
|
<view style="display: flex; justify-content: space-between">
|
||||||
|
<text>项目负责人:{{serviceProject.projectManagerMiniProgramUserInfo?.name?serviceProject.projectManagerMiniProgramUserInfo?.name:'无分配项目经理'}}</text>
|
||||||
|
</view>
|
||||||
|
<view>责任单位:{{serviceProject.securityUnitName}}</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -37,10 +46,9 @@ import './myProject.scss'
|
||||||
import {MyProjectList, ServiceProjectList} from "@/types/subPages/projectManager/myProject";
|
import {MyProjectList, ServiceProjectList} from "@/types/subPages/projectManager/myProject";
|
||||||
|
|
||||||
const myProjectList = ref<MyProjectList[]>()
|
const myProjectList = ref<MyProjectList[]>()
|
||||||
|
|
||||||
const number = ref(0)
|
const number = ref(0)
|
||||||
const getMyServiceProject = async () => {
|
const getMyServiceProject = async () => {
|
||||||
const resp = await api.get<MyProjectList[]>(`/projectManageIndex/getMyServiceProject`)
|
const resp = await api.get<MyProjectList[]>(`/mp/pmi/get_my_sp`)
|
||||||
myProjectList.value = resp.data
|
myProjectList.value = resp.data
|
||||||
number.value = (resp.data?.length || 0)
|
number.value = (resp.data?.length || 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<view style="display: flex;justify-content: space-between">
|
<view style="display: flex;justify-content: space-between">
|
||||||
<text style="font-size: 18px">{{ enterprisesUnitName }}-----{{ serviceProject?.name }}
|
<text style="font-size: 18px">{{ enterprisesUnitName }}-----{{ serviceProject?.name }}
|
||||||
</text>
|
</text>
|
||||||
<text>进行中</text>
|
<!-- <text>进行中</text>-->
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<view style="float: left;width: 50%;" class="content">
|
<view style="float: left;width: 50%;" class="content">
|
||||||
|
@ -62,12 +62,12 @@
|
||||||
<text>职位:{{ item.workPost ? item.workPost : '无' }}</text>
|
<text>职位:{{ item.workPost ? item.workPost : '无' }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view style="display: flex;justify-content: space-between">
|
<view style="display: flex;justify-content: space-between">
|
||||||
<text>保安证件:{{ item.securityNumber ? item.securityNumber : '125241256451' }}</text>
|
<text>保安证件:{{ item.securityNumber ? item.securityNumber : '无' }}</text>
|
||||||
<text>出生年月:{{ dayjs(item.dateOfBirth).format('YYYY-MM-DD') }}</text>
|
<text>出生年月:{{ dayjs(item.dateOfBirth).format('YYYY-MM-DD') }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view style="display: flex;justify-content: space-between">
|
<view style="display: flex;justify-content: space-between">
|
||||||
<text>创建时间:{{ item.createTime }}</text>
|
<text>创建时间:{{ item.createTime }}</text>
|
||||||
<text>身份证:{{ item.idCard }}</text>
|
<text>身份证:{{ item.idCard?.desensitizedValue }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="projectDetailsTableIndex">
|
<view class="projectDetailsTableIndex">
|
||||||
|
@ -169,7 +169,7 @@ const projectDetailsTable = async () => {
|
||||||
current: current.value
|
current: current.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const resp = await api.post<PagerVo<ServiceProjectSecurityUserPagerVo>>('/miniProgramUser/securityUserPager', queryParams)
|
const resp = await api.post<PagerVo<ServiceProjectSecurityUserPagerVo>>('/mp/user/securityUserPager', queryParams)
|
||||||
securityUserList.value = [...securityUserList.value, ...resp.data!.records]
|
securityUserList.value = [...securityUserList.value, ...resp.data!.records]
|
||||||
total.value = resp.data!.total
|
total.value = resp.data!.total
|
||||||
isRefresher.value = false
|
isRefresher.value = false
|
||||||
|
@ -189,7 +189,9 @@ const formAdd = () => {
|
||||||
securityNumber: '',
|
securityNumber: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
homeAddress: '',
|
homeAddress: '',
|
||||||
telephone: ''
|
telephone: '',
|
||||||
|
photo:'',
|
||||||
|
noSecurityNumberDesc:''
|
||||||
} as SecurityUserFormParams
|
} as SecurityUserFormParams
|
||||||
Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&&type=formInput`})
|
Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&&type=formInput`})
|
||||||
}
|
}
|
||||||
|
@ -228,7 +230,7 @@ const deleteUssrID = (snowFlakeId: string) => {
|
||||||
}
|
}
|
||||||
// 二次删除
|
// 二次删除
|
||||||
const dialogOk = async () => {
|
const dialogOk = async () => {
|
||||||
await api.delete(`/projectManageIndex/deleteSecurityUserByServiceProjectId`, {securityUserId: securityUserId.value})
|
await api.delete(`/mp/user/del_security_user_id`, {securityUserId: securityUserId.value})
|
||||||
initServiceProjectSecurityUserList()
|
initServiceProjectSecurityUserList()
|
||||||
}
|
}
|
||||||
// 详情
|
// 详情
|
||||||
|
@ -237,6 +239,7 @@ const detail = (item: ServiceProjectSecurityUserPagerVo) => {
|
||||||
securityUserDetail.value = item
|
securityUserDetail.value = item
|
||||||
}
|
}
|
||||||
const securityUserEdit = (item: ServiceProjectSecurityUserPagerVo) => {
|
const securityUserEdit = (item: ServiceProjectSecurityUserPagerVo) => {
|
||||||
|
console.log(item)
|
||||||
const params = {...item, sex: item.sex.value}
|
const params = {...item, sex: item.sex.value}
|
||||||
Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&type=formInput`})
|
Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&type=formInput`})
|
||||||
}
|
}
|
||||||
|
@ -248,7 +251,7 @@ const generateMiniProgramQRCode = async () => {
|
||||||
width: 200,
|
width: 200,
|
||||||
}
|
}
|
||||||
qrcodeVisible.value = true
|
qrcodeVisible.value = true
|
||||||
const resp = await api.get('/projectManageIndex/shareForm_QR_Code', paramsData, {
|
const resp = await api.get('/wx/qrCode', paramsData, {
|
||||||
header: {
|
header: {
|
||||||
"content-type": 'application/x-www-form-urlencoded'
|
"content-type": 'application/x-www-form-urlencoded'
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +1,20 @@
|
||||||
.form {
|
.form {
|
||||||
.formButton {
|
.formButton {
|
||||||
|
//position: fixed;
|
||||||
|
bottom: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-top: auto;
|
-webkit-justify-content: space-around;
|
||||||
justify-content: space-around;
|
margin-bottom: 10rpx;
|
||||||
margin-bottom: 30px
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 140px
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.uploadPictures{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 220px;
|
||||||
|
height: 254px;
|
||||||
|
border: 2px solid #d5d3d3;
|
||||||
|
}
|
||||||
|
|
|
@ -1,30 +1,40 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="form">
|
<view class="form">
|
||||||
<nut-form ref="formRef" :model-value="formData" :rules="rules">
|
<nut-form ref="formRef" :model-value="formData" :rules="rules">
|
||||||
|
<nut-form-item label="头像" prop="avatar">
|
||||||
|
<!-- <view class="uploadPictures" @click="chooseImage">-->
|
||||||
|
<!-- <view v-if="!formData.photo">-->
|
||||||
|
<!-- <IconFont name="uploader" size="25" color="#98a7b0"></IconFont>-->
|
||||||
|
<!-- </view>-->
|
||||||
|
<!-- <image v-else :src="minioBaseUrl +formData.photo" style="width: 100%; height: 100%"></image>-->
|
||||||
|
<!-- </view>-->
|
||||||
|
<view @click="chooseImage" size>
|
||||||
|
<image v-if="!formData.photo" src="@/assets/logo/avatar1.png" style="width: 50px; height: 50px"></image>
|
||||||
|
<image v-else :src="minioBaseUrl +formData.photo" style="width: 160px; height: 128px"></image>
|
||||||
|
</view>
|
||||||
|
</nut-form-item>
|
||||||
|
<nut-form-item label="身份证" prop="idCard">
|
||||||
|
<view style="display: flex; justify-content: space-between; align-items: center">
|
||||||
|
<nut-input v-model="formData.idCard" placeholder="请填写身份证" type="text" @blur="cardBlur" />
|
||||||
|
<view style="color: #3a6bbe; width: 70px; text-align: center" @click="idCardBlur(formData, 0)">查询</view>
|
||||||
|
</view>
|
||||||
|
</nut-form-item>
|
||||||
<nut-form-item label="姓名" prop="name">
|
<nut-form-item label="姓名" prop="name">
|
||||||
<nut-input v-model="formData.name" placeholder="请输入姓名" type="text" />
|
<nut-input v-model="formData.name" placeholder="请输入姓名" type="text" />
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
<nut-form-item label="性别" prop="sex">
|
<nut-form-item label="性别" prop="sex">
|
||||||
<nut-radio-group v-model="formData.sex" direction="horizontal">
|
<nut-radio-group v-model="formData.sex" direction="horizontal">
|
||||||
<nut-radio v-for="item in SEX" :key="item.value" :label="item.value"
|
<nut-radio v-for="item in SEX" :key="item.value" :label="item.value">{{ item.label }} </nut-radio>
|
||||||
>{{ item.label }}
|
|
||||||
</nut-radio>
|
|
||||||
</nut-radio-group>
|
</nut-radio-group>
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
<nut-form-item label="身份证" prop="idCard">
|
|
||||||
<nut-input v-model="formData.idCard" placeholder="请填写身份证" type="text" @blur="idCardBlur"/>
|
|
||||||
</nut-form-item>
|
|
||||||
<nut-form-item label="出生日期" prop="dateOfBirth">
|
<nut-form-item label="出生日期" prop="dateOfBirth">
|
||||||
<view @click="showPicker = true">
|
<view @click="showPicker = true">
|
||||||
{{
|
{{ formData.dateOfBirth ? dayjs(formData.dateOfBirth).format('YYYY-MM-DD') : '请选择出生年月' }}
|
||||||
formData.dateOfBirth ? dayjs(formData.dateOfBirth).format('YYYY-MM-DD') : '请选择出生年月'
|
|
||||||
}}
|
|
||||||
</view>
|
</view>
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
<nut-form-item label="工作岗位" prop="workPost">
|
<nut-form-item label="工作岗位" prop="workPost">
|
||||||
<nut-input v-model="formData.workPost" placeholder="请输入工作岗位" type="text" />
|
<nut-input v-model="formData.workPost" placeholder="请输入工作岗位" type="text" />
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
|
|
||||||
<nut-form-item label="手机号" prop="telephone">
|
<nut-form-item label="手机号" prop="telephone">
|
||||||
<nut-input v-model="formData.telephone" placeholder="请输入手机号" type="text" />
|
<nut-input v-model="formData.telephone" placeholder="请输入手机号" type="text" />
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
|
@ -34,16 +44,19 @@
|
||||||
<nut-form-item label="地址" prop="homeAddress">
|
<nut-form-item label="地址" prop="homeAddress">
|
||||||
<nut-input v-model="formData.homeAddress" placeholder="请输入地址" type="text" />
|
<nut-input v-model="formData.homeAddress" placeholder="请输入地址" type="text" />
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
<nut-form-item label="保安证号" prop="securityNumber">
|
<nut-form-item label="保安证件号" prop="securityNumber">
|
||||||
<nut-input v-model="formData.securityNumber" placeholder="请输入保安证号" type="text" />
|
<nut-input v-model="formData.securityNumber" placeholder="请输入保安证号" type="text" />
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
|
<nut-form-item label="无证说明" v-if="!formData.securityNumber">
|
||||||
|
<nut-input v-model="formData.noSecurityNumberDesc" placeholder="无证说明" type="text" />
|
||||||
|
</nut-form-item>
|
||||||
<nut-form-item label="备注" prop="remark">
|
<nut-form-item label="备注" prop="remark">
|
||||||
<nut-input v-model="formData.remark" placeholder="请填写备注" type="text" />
|
<nut-input v-model="formData.remark" placeholder="请填写备注" type="text" />
|
||||||
</nut-form-item>
|
</nut-form-item>
|
||||||
</nut-form>
|
</nut-form>
|
||||||
<view class="formButton">
|
<view class="formButton">
|
||||||
<nut-button style="width: 45%" type="success" size="small" @click="submit">提交</nut-button>
|
<nut-button style="width: 45%" type="success" size="small" @click="submit">提交</nut-button>
|
||||||
<nut-button style="width: 45%" size="small" @click="formRef?.reset()">重置表单</nut-button>
|
<nut-button style="width: 45%" size="small" @click="reset">重置表单</nut-button>
|
||||||
</view>
|
</view>
|
||||||
<nut-popup v-model:visible="showPicker" position="bottom">
|
<nut-popup v-model:visible="showPicker" position="bottom">
|
||||||
<nut-date-picker
|
<nut-date-picker
|
||||||
|
@ -55,81 +68,176 @@
|
||||||
@cancel="showPicker = false"
|
@cancel="showPicker = false"
|
||||||
></nut-date-picker>
|
></nut-date-picker>
|
||||||
</nut-popup>
|
</nut-popup>
|
||||||
|
<nut-dialog content="详情" v-model:visible="visible" @ok="onOk" @cancel="cancel">
|
||||||
|
<slot>
|
||||||
|
<view style="margin-bottom: 5px">
|
||||||
|
<view>姓名:{{ securityNumberByIdCard?.name ? securityNumberByIdCard?.name : '无' }}</view>
|
||||||
|
<view>保安证件号:{{ securityNumberByIdCard?.bayzh ? securityNumberByIdCard?.bayzh : '无' }}</view>
|
||||||
|
<view>身份证:{{ securityNumberByIdCard?.sfzhm ? securityNumberByIdCard?.sfzhm : '无' }}</view>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</nut-dialog>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from "vue";
|
import { ref } from 'vue'
|
||||||
import {enumSelectNodes} from "@/enums";
|
import { enumSelectNodes } from '@/enums'
|
||||||
import {FormRules} from "@nutui/nutui-taro/dist/types/__VUE/form/types";
|
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'
|
||||||
import api from "@/request";
|
import api from '@/request'
|
||||||
import './securityUserForm.scss'
|
import './securityUserForm.scss'
|
||||||
import Taro, {useLoad} from "@tarojs/taro";
|
import Taro, { useLoad } from '@tarojs/taro'
|
||||||
import dayjs from "dayjs";
|
import dayjs from 'dayjs'
|
||||||
import {SecurityUserFormParams} from "@/types/subPages/projectManager/securityUserForm";
|
import { SecurityUserFormParams, securityNumberByIdCard } from '@/types/subPages/projectManager/securityUserForm'
|
||||||
import {FormInstance} from "@nutui/nutui-taro";
|
import { FormInstance } from '@nutui/nutui-taro'
|
||||||
|
import { generateSimpleObjectName, getResignedObjectUrl } from '@/utils'
|
||||||
|
import {IconFont} from "@nutui/icons-vue-taro";
|
||||||
|
|
||||||
const SEX = enumSelectNodes('Sex')
|
const SEX = enumSelectNodes('Sex')
|
||||||
|
const minioBaseUrl = process.env.TARO_APP_MINIO_URL
|
||||||
const showPicker = ref(false)
|
const showPicker = ref(false)
|
||||||
|
const Url = ref('')
|
||||||
const type = ref<'formInput' | 'QcCodeInput'>(null!);
|
const type = ref<'formInput' | 'QcCodeInput'>(null!)
|
||||||
|
|
||||||
const formData = ref<SecurityUserFormParams>({} as any)
|
const formData = ref<SecurityUserFormParams>({} as any)
|
||||||
const formRef = ref<FormInstance>(null!)
|
const formRef = ref<FormInstance>(null!)
|
||||||
|
const visible = ref<boolean>(false)
|
||||||
|
const securityNumberByIdCard = ref<securityNumberByIdCard>()
|
||||||
|
const uploadRef = ref<any>(null)
|
||||||
|
const modelValue = ref('')
|
||||||
|
|
||||||
const rules: FormRules = {
|
const rules: FormRules = {
|
||||||
name: [
|
name: [{ required: true, message: '请输入姓名' }],
|
||||||
{required: true, message: "请输入姓名"},
|
sex: [{ required: true, message: '请选择性别' }],
|
||||||
],
|
|
||||||
sex: [{required: true, message: "请选择性别"}],
|
|
||||||
idCard: [
|
idCard: [
|
||||||
{required: true, message: "请输入身份证号"},
|
{ required: true, message: '请输入身份证号' },
|
||||||
{
|
{
|
||||||
regex: /^(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))((0[1-9])|([12][0-9])|(30|31))\d{3}(\d|X)$)/,
|
regex: /^(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))((0[1-9])|([12][0-9])|(30|31))\d{3}(\d|X)$)/,
|
||||||
message: "身份证格式错误",
|
message: '身份证格式错误',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
telephone: [
|
telephone: [{ required: true, message: '请输入手机号' }],
|
||||||
{required: true, message: "请输入手机号"},
|
}
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
useLoad((options) => {
|
useLoad((options) => {
|
||||||
type.value = options.type;
|
type.value = options.type
|
||||||
if (type.value === 'QcCodeInput') {
|
if (type.value === 'QcCodeInput') {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
|
name: '',
|
||||||
serviceProjectId: options.pid,
|
serviceProjectId: options.pid,
|
||||||
securityUnitId: options.uid,
|
securityUnitId: options.uid,
|
||||||
sex: 0,
|
sex: 0,
|
||||||
idCard: '',
|
idCard: null,
|
||||||
dateOfBirth: null
|
telephone: null,
|
||||||
|
dateOfBirth: null,
|
||||||
|
noSecurityNumberDesc: options.noSecurityNumberDesc,
|
||||||
|
photo: '',
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
formData.value = JSON.parse(options.securityUser)
|
const form = JSON.parse(options.securityUser)
|
||||||
|
formData.value = Object.assign({}, form, {
|
||||||
|
idCard: form.idCard.originalValue,
|
||||||
|
telephone: form.telephone.originalValue,
|
||||||
|
photo: form.photo
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const idCardBlur = (e: any) => {
|
const idCardBlur = async (e: any, num: number) => {
|
||||||
const value = e.detail.value
|
const value = e.idCard
|
||||||
|
if (value) {
|
||||||
|
Taro.request({
|
||||||
|
url: 'https://www.hnjinglian.cn:5678/common/querySecurityNumberByIdCard',
|
||||||
|
data: {
|
||||||
|
idCard: value,
|
||||||
|
},
|
||||||
|
method: 'GET',
|
||||||
|
success: ({ data }) => {
|
||||||
|
visible.value = true
|
||||||
|
securityNumberByIdCard.value = data.data
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
visible.value = false
|
||||||
|
console.log(value)
|
||||||
|
}
|
||||||
|
cardBlur(value, num)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardBlur = (e, num) => {
|
||||||
|
let value = ''
|
||||||
|
if (num === 0) {
|
||||||
|
value = e
|
||||||
|
} else {
|
||||||
|
value = e.detail.value
|
||||||
|
}
|
||||||
if (!value?.length || value.length < 18) {
|
if (!value?.length || value.length < 18) {
|
||||||
formData.value.dateOfBirth = null;
|
formData.value.dateOfBirth = null
|
||||||
|
cancel()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const birthDate = value.substring(6, 14);
|
const birthDate = value.substring(6, 14)
|
||||||
const year = birthDate.substring(0, 4);
|
const year = birthDate.substring(0, 4)
|
||||||
const month = birthDate.substring(4, 6);
|
const month = birthDate.substring(4, 6)
|
||||||
const day = birthDate.substring(6, 8);
|
const day = birthDate.substring(6, 8)
|
||||||
formData.value.dateOfBirth = new Date(parseInt(year), parseInt(month) - 1, parseInt(day))
|
formData.value.dateOfBirth = new Date(parseInt(year), parseInt(month) - 1, parseInt(day))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onOk = () => {
|
||||||
|
formData.value.securityNumber = securityNumberByIdCard.value?.bayzh
|
||||||
|
formData.value.name = securityNumberByIdCard.value?.name
|
||||||
|
}
|
||||||
|
const cancel = () => {
|
||||||
|
formData.value.securityNumber = ''
|
||||||
|
formData.value.name = ''
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
const chooseImage = () => {
|
||||||
|
Taro.chooseMedia({
|
||||||
|
count: 1, // 选择一个文件
|
||||||
|
mediaType: ['image', 'video'],
|
||||||
|
sourceType: ['album', 'camera'],
|
||||||
|
sizeType:['original', 'compressed'],
|
||||||
|
camera: 'front',
|
||||||
|
success: async (res) => {
|
||||||
|
Url.value = res.tempFiles[0].tempFilePath
|
||||||
|
const objectName = generateSimpleObjectName(Url.value, '/securityUser')
|
||||||
|
const uploadUrl = await getResignedObjectUrl(process.env.TARO_APP_MINIO_BUCKET, objectName)
|
||||||
|
|
||||||
|
modelValue.value = '/' + process.env.TARO_APP_MINIO_BUCKET + objectName
|
||||||
|
// 使用 wx.getFileSystemManager().readFileSync 读取文件的二进制内容
|
||||||
|
const fs = Taro.getFileSystemManager()
|
||||||
|
const fileData = fs.readFileSync(Url.value) // 返回的是文件的二进制内容
|
||||||
|
// 发送 PUT 请求上传二进制文件
|
||||||
|
Taro.request({
|
||||||
|
url: uploadUrl, // 后端上传接口
|
||||||
|
method: 'PUT',
|
||||||
|
header: {
|
||||||
|
'Content-Type': 'application/octet-stream', // 设置为二进制流
|
||||||
|
},
|
||||||
|
data: fileData, // 传递二进制数据
|
||||||
|
success(res) {
|
||||||
|
formData.value.photo = modelValue.value
|
||||||
|
console.log('上传成功', res)
|
||||||
|
},
|
||||||
|
fail(err) {
|
||||||
|
console.error('上传失败', err)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fail(err) {
|
||||||
|
console.error('选择文件失败', err)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
|
formData.value.photo = modelValue.value
|
||||||
formRef.value?.validate().then(async ({ valid }) => {
|
formRef.value?.validate().then(async ({ valid }) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let url: string;
|
let url: string
|
||||||
if (type.value === 'formInput') {
|
if (type.value === 'formInput') {
|
||||||
url = '/projectManageIndex/saveOrUpdateSecurityUser'
|
url = '/mp/user/add_security_user_upd'
|
||||||
} else {
|
} else {
|
||||||
url = '/miniProgramUser/qrCodeFormInputSecurityUser'
|
url = '/mp/user/qrCodeFormInputSecurityUser'
|
||||||
}
|
}
|
||||||
const resp = await api.post(url, formData.value)
|
const resp = await api.post(url, formData.value)
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
|
@ -144,16 +252,23 @@ const submit = () => {
|
||||||
securityUnitId: formData.value.securityUnitId,
|
securityUnitId: formData.value.securityUnitId,
|
||||||
name: '',
|
name: '',
|
||||||
workPost: '',
|
workPost: '',
|
||||||
telephone: '',
|
telephone: null,
|
||||||
sex: 0,
|
sex: 0,
|
||||||
nativePlace: '',
|
nativePlace: '',
|
||||||
idCard: '',
|
idCard: null,
|
||||||
dateOfBirth: null,
|
dateOfBirth: null,
|
||||||
securityNumber: '',
|
securityNumber: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
homeAddress: ''
|
homeAddress: '',
|
||||||
|
noSecurityNumberDesc: '',
|
||||||
|
photo: '',
|
||||||
}
|
}
|
||||||
|
uploadRef.value?.clearUploadQueue()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
formRef.value?.reset()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
.userinform {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.userItem {
|
||||||
|
color: #7b7b7b;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
.textIndex {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.singleChoice {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '',
|
||||||
|
})
|
|
@ -0,0 +1,121 @@
|
||||||
|
<template>
|
||||||
|
<view class="userinform">
|
||||||
|
<view class="userItem">
|
||||||
|
<!-- v-model="item.snowFlakeId" 展开所有 -->
|
||||||
|
<nut-collapse v-model="item.snowFlakeId" accordion v-for="(item, index) in starRating[findIndex].itemList" :key="item.snowFlakeId">
|
||||||
|
<nut-collapse-item :name="item.snowFlakeId" :title="item.name">
|
||||||
|
<view class="singleChoice">
|
||||||
|
<nut-radio-group v-if="item.type.value === 'radio'" v-model="item.selectedID" @change="(modelValue) => onChange(modelValue, item.name)">
|
||||||
|
<nut-radio v-for="(items, indexs) in item.standardList" size="40" :label="items.snowFlakeId" :key="indexs"> {{ items.name }}</nut-radio>
|
||||||
|
</nut-radio-group>
|
||||||
|
<!-- 不能直接去更改 v-model 绑定的 这个数据 ,否则会造成无限递归-->
|
||||||
|
<nut-checkbox-group v-else v-model="item.selectedGroup" @change="(arr) => checkboxGroupChange(arr, index)" style="display: flex; flex-direction: column">
|
||||||
|
<nut-checkbox
|
||||||
|
v-model="items.isSelected"
|
||||||
|
@change="(state, label) => checkboxChange(state, label, index, i)"
|
||||||
|
v-for="(items, i) in item.standardList"
|
||||||
|
size="40"
|
||||||
|
:label="items.snowFlakeId"
|
||||||
|
:key="i"
|
||||||
|
style="margin-bottom: 20rpx"
|
||||||
|
shape="button"
|
||||||
|
>{{ items.name}}</nut-checkbox
|
||||||
|
>
|
||||||
|
</nut-checkbox-group>
|
||||||
|
</view>
|
||||||
|
</nut-collapse-item>
|
||||||
|
</nut-collapse>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import Taro, { useLoad, useUnload } from '@tarojs/taro'
|
||||||
|
import { ref, computed, watch, nextTick } from 'vue'
|
||||||
|
|
||||||
|
import { useDailyStore } from '@/store/daily.ts'
|
||||||
|
const store = useDailyStore()
|
||||||
|
const starRating = ref([])
|
||||||
|
const findIndex = ref(0)
|
||||||
|
const airdefenceEnumdata = ref([])
|
||||||
|
useLoad((options) => {
|
||||||
|
Taro.setNavigationBarTitle({
|
||||||
|
title: options.name,
|
||||||
|
})
|
||||||
|
|
||||||
|
findIndex.value = options.index
|
||||||
|
})
|
||||||
|
|
||||||
|
const daily = computed(() => store.getdailyinspection)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
daily,
|
||||||
|
(newData) => {
|
||||||
|
starRating.value = newData
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @assessmentRecordDetails 选择后的数据用于提交
|
||||||
|
*/
|
||||||
|
const assessmentRecordDetails = ref([])
|
||||||
|
|
||||||
|
const onChange = (modelValue, name) => {
|
||||||
|
starRating.value[findIndex.value].itemList.forEach((element) => {
|
||||||
|
if (name === element.name) {
|
||||||
|
element.selectedID = modelValue
|
||||||
|
element.standardList.forEach((item) => {
|
||||||
|
if (item.snowFlakeId == modelValue) {
|
||||||
|
element.selected_points = item.deductionPoints //添加扣分项
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkboxGroupChange = function (arr, index) {
|
||||||
|
let points = 0
|
||||||
|
|
||||||
|
starRating.value[findIndex.value].itemList.forEach((element, i) => {
|
||||||
|
if (i === index) {
|
||||||
|
element.selectedGroup.forEach((selectedId) => {
|
||||||
|
element.standardList.forEach((standardItem) => {
|
||||||
|
if (selectedId === standardItem.snowFlakeId) {
|
||||||
|
points += standardItem.deductionPoints
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
starRating.value[findIndex.value].itemList[index].selected_points = points
|
||||||
|
}
|
||||||
|
const checkboxChange = async function (state, label, index, i) {
|
||||||
|
// DOM 还未更新
|
||||||
|
await nextTick() //等待下一次 DOM 更新刷新的工具方法。
|
||||||
|
// DOM 此时已经更新
|
||||||
|
|
||||||
|
let arr
|
||||||
|
|
||||||
|
if (label === '达标' && i === 0) {
|
||||||
|
arr = ['null']
|
||||||
|
} else {
|
||||||
|
arr = starRating.value[findIndex.value].itemList[index].selectedGroup.filter((selectedId) => selectedId != 'null')
|
||||||
|
}
|
||||||
|
if (arr?.length === 0) {
|
||||||
|
arr = ['null']
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JSON.stringify(arr) !== JSON.stringify(starRating.value[findIndex.value].itemList[index].selectedGroup)) {
|
||||||
|
starRating.value[findIndex.value].itemList[index].selectedGroup = arr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
useUnload(() => {
|
||||||
|
let points = 0
|
||||||
|
starRating.value[findIndex.value].itemList.forEach((element) => {
|
||||||
|
points += element.selected_points
|
||||||
|
})
|
||||||
|
starRating.value[findIndex.value].currentScore = points
|
||||||
|
store.dailyinspectionList([...starRating.value])
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,65 @@
|
||||||
|
.sign-box {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 100;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixedIcon {
|
||||||
|
z-index: 1000;
|
||||||
|
position: fixed;
|
||||||
|
right: 20px;
|
||||||
|
top: 20px;
|
||||||
|
height: 100rpx;
|
||||||
|
width: 100rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-view {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sigh_btns_false {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 15rpx;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.sigh_btns {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
transform-origin: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.sigh_btns_noRotate {}
|
||||||
|
|
||||||
|
.sigh_btns_true {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 20%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.mycanvas {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #ececec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvsborder {
|
||||||
|
border: 1rpx solid #333;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 10000rpx;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '签名',
|
||||||
|
disableScroll: true
|
||||||
|
})
|
|
@ -0,0 +1,174 @@
|
||||||
|
<template>
|
||||||
|
<!-- 签字功能 -->
|
||||||
|
<view catchtouchmove="true">
|
||||||
|
<view class="sign-box">
|
||||||
|
<view class="fixedIcon" @click.stop="changeDirection">
|
||||||
|
<image style="height: 100rpx; width: 100rpx" :src="icon"></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<canvas class="mycanvas" :style="{ height: height + 'px' }" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas>
|
||||||
|
<canvas canvas-id="camCacnvs" :style="{ height: width + 'px' }" class="canvsborder"></canvas>
|
||||||
|
|
||||||
|
<view :class="direction ? 'sigh_btns_true' : 'sigh_btns_false'">
|
||||||
|
<nut-button :class="direction ? 'sigh_btns' : 'sigh_btns_noRotate'" style="height: 60rpx" shape="square" type="info" @click="handleCancel"> 取消 </nut-button>
|
||||||
|
<nut-button :class="direction ? 'sigh_btns' : 'sigh_btns_noRotate'" style="height: 60rpx" shape="square" type="info" @click="handleReset"> 重写 </nut-button>
|
||||||
|
<nut-button :class="direction ? 'sigh_btns' : 'sigh_btns_noRotate'" style="height: 60rpx" shape="square" type="info" @click="handleConfirm"> 确认 </nut-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import './signature.scss'
|
||||||
|
import Taro, { useLoad, useUnload } from '@tarojs/taro'
|
||||||
|
import { ref, onMounted, watch, computed } from 'vue'
|
||||||
|
import icon from '@/assets/images/rotate1.png'
|
||||||
|
const _index = ref(0)
|
||||||
|
import { useDailyStore } from '@/store/daily'
|
||||||
|
const store = useDailyStore()
|
||||||
|
|
||||||
|
const width = ref(0)
|
||||||
|
const height = ref(300)
|
||||||
|
const points = ref([]) // 画笔路径点集合
|
||||||
|
const tempPoint = ref([]) // 当前签名路径
|
||||||
|
let that
|
||||||
|
let id
|
||||||
|
let type
|
||||||
|
useLoad((options) => {
|
||||||
|
_index.value = Number(options.index)
|
||||||
|
Taro.setNavigationBarTitle({
|
||||||
|
title: options.name,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const ctx = ref(null)
|
||||||
|
onMounted(() => {
|
||||||
|
that = this
|
||||||
|
const { windowWidth, windowHeight } = Taro.getSystemInfoSync()
|
||||||
|
width.value = windowWidth
|
||||||
|
height.value = windowHeight * 0.98 // 控制画板的宽高
|
||||||
|
|
||||||
|
// 创建绘图上下文
|
||||||
|
ctx.value = Taro.createCanvasContext('mycanvas', this)
|
||||||
|
ctx.value.lineWidth = 2
|
||||||
|
ctx.value.lineCap = 'round'
|
||||||
|
ctx.value.lineJoin = 'round'
|
||||||
|
})
|
||||||
|
|
||||||
|
const touchstart = (e) => {
|
||||||
|
const startX = e.changedTouches[0].x
|
||||||
|
const startY = e.changedTouches[0].y
|
||||||
|
points.value.push({ X: startX, Y: startY })
|
||||||
|
ctx.value.beginPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
const touchmove = (e) => {
|
||||||
|
const moveX = e.changedTouches[0].x
|
||||||
|
const moveY = e.changedTouches[0].y
|
||||||
|
points.value.push({ X: moveX, Y: moveY })
|
||||||
|
if (points.value.length >= 2) {
|
||||||
|
draw()
|
||||||
|
}
|
||||||
|
tempPoint.value.push({ X: moveX, Y: moveY })
|
||||||
|
}
|
||||||
|
|
||||||
|
const touchend = () => {
|
||||||
|
points.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const draw = () => {
|
||||||
|
const point1 = points.value[0]
|
||||||
|
const point2 = points.value[1]
|
||||||
|
points.value.shift()
|
||||||
|
ctx.value.moveTo(point1.X, point1.Y)
|
||||||
|
ctx.value.lineTo(point2.X, point2.Y)
|
||||||
|
ctx.value.stroke()
|
||||||
|
ctx.value.draw(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
Taro.navigateBack({ delta: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
ctx.value.clearRect(0, 0, width.value, height.value)
|
||||||
|
ctx.value.draw(true)
|
||||||
|
tempPoint.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
if (tempPoint.value.length === 0) {
|
||||||
|
Taro.showToast({ title: '请先签名', icon: 'none', duration: 2000 })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Taro.canvasToTempFilePath({
|
||||||
|
canvasId: 'mycanvas',
|
||||||
|
success: (res) => {
|
||||||
|
console.log('canvasToTempFilePath______________', res)
|
||||||
|
|
||||||
|
const tempPath = res.tempFilePath
|
||||||
|
const ctx = Taro.createCanvasContext('camCacnvs', that)
|
||||||
|
const scale = 0.5
|
||||||
|
var targetWidth
|
||||||
|
var targetHeight
|
||||||
|
// 前置图片旋转处理 ___________________________________________________________________
|
||||||
|
if (direction.value) {
|
||||||
|
targetWidth = height.value * scale
|
||||||
|
targetHeight = width.value * scale
|
||||||
|
// 计算旋转后的外接矩形尺寸
|
||||||
|
const angle = (270 * Math.PI) / 180 // 逆时针旋转 270 度
|
||||||
|
const rotatedWidth = Math.abs(width.value * Math.cos(angle)) + Math.abs(height.value * Math.sin(angle))
|
||||||
|
const rotatedHeight = Math.abs(height.value * Math.cos(angle)) + Math.abs(width.value * Math.sin(angle))
|
||||||
|
// 计算平移量
|
||||||
|
const offsetX = 0 // 如果不需要水平偏移,则为 0
|
||||||
|
const offsetY = rotatedHeight - targetHeight // 计算 y 轴的平移量
|
||||||
|
// 将画布原点平移到适当位置
|
||||||
|
ctx.translate(offsetX, offsetY)
|
||||||
|
// 旋转画布
|
||||||
|
ctx.rotate(angle)
|
||||||
|
ctx.drawImage(tempPath, 0, 0, targetHeight, targetWidth)
|
||||||
|
} else {
|
||||||
|
targetWidth = width.value * scale
|
||||||
|
targetHeight = height.value * scale
|
||||||
|
ctx.drawImage(tempPath, 0, 0, targetWidth, targetHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.draw(false, () => {
|
||||||
|
Taro.canvasToTempFilePath({
|
||||||
|
canvasId: 'camCacnvs',
|
||||||
|
width: targetWidth,
|
||||||
|
height: targetHeight,
|
||||||
|
success: (compressedRes) => {
|
||||||
|
Taro.getFileSystemManager().readFile({
|
||||||
|
filePath: compressedRes.tempFilePath,
|
||||||
|
encoding: 'base64',
|
||||||
|
success: (res) => {
|
||||||
|
const base64Image = 'data:image/jpeg;base64,' + res.data
|
||||||
|
|
||||||
|
console.log('base64Image_________________________', base64Image)
|
||||||
|
|
||||||
|
if (_index.value === 1) {
|
||||||
|
store.change_base64_1(base64Image)
|
||||||
|
Taro.navigateBack({ delta: 1 })
|
||||||
|
} else {
|
||||||
|
store.change_base64_2(base64Image)
|
||||||
|
Taro.navigateBack({ delta: 1 })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @direction false 竖屏,true 横屏
|
||||||
|
*/
|
||||||
|
|
||||||
|
const direction = ref(true)
|
||||||
|
const changeDirection = () => {
|
||||||
|
direction.value = !direction.value
|
||||||
|
Taro.vibrateShort({ type: 'medium' }).then()
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,23 @@
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import api from "@/request";
|
||||||
|
|
||||||
|
export const generateSimpleObjectName = (fileName: string, parentDir?: String): string => {
|
||||||
|
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||||
|
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
let objectName = parentDir + dayjs().format('/YYYY/MM/DD/') + uuid.replace(/-/g, '');
|
||||||
|
console.log(fileName,objectName,'4444')
|
||||||
|
if (fileName && fileName.length > 0) {
|
||||||
|
objectName += fileName.substring(fileName.lastIndexOf('.'))
|
||||||
|
}
|
||||||
|
console.log(objectName,'888')
|
||||||
|
return objectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getResignedObjectUrl = async (bucketName: string, objectName: string): Promise<string> => {
|
||||||
|
return (await api.get<string>('/common/getResignedObjectUrl', {
|
||||||
|
bucketName,
|
||||||
|
objectName
|
||||||
|
})).data as string;
|
||||||
|
}
|
|
@ -25,6 +25,10 @@ declare namespace NodeJS {
|
||||||
TARO_APP_ID: string
|
TARO_APP_ID: string
|
||||||
/** 后台服务接口地址 **/
|
/** 后台服务接口地址 **/
|
||||||
TARO_APP_BASE_API: string
|
TARO_APP_BASE_API: string
|
||||||
|
|
||||||
|
TARO_APP_MINIO_BUCKET:string
|
||||||
|
|
||||||
|
TARO_APP_MINIO_URL:string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,3 +106,59 @@ interface BaseEnum<T, E = Record<string, any>> {
|
||||||
label: string;
|
label: string;
|
||||||
extData: E;
|
extData: E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface StandardList {
|
||||||
|
ckItemId: string
|
||||||
|
deductionPoints: number
|
||||||
|
name: string
|
||||||
|
snowFlakeId: string
|
||||||
|
isSelected: boolean
|
||||||
|
}
|
||||||
|
interface ItemList {
|
||||||
|
ckGroupId: string
|
||||||
|
name: string
|
||||||
|
remark: string
|
||||||
|
snowFlakeId: string
|
||||||
|
standardList: StandardList[]
|
||||||
|
type: { value: string; label: string }
|
||||||
|
selectedID: string
|
||||||
|
selected_points: number
|
||||||
|
selectedGroup: any[]
|
||||||
|
}
|
||||||
|
interface StarRating {
|
||||||
|
itemList: ItemList[]
|
||||||
|
name: string
|
||||||
|
remark: string
|
||||||
|
snowFlakeId: string
|
||||||
|
totalScore: number
|
||||||
|
currentScore: number
|
||||||
|
}
|
||||||
|
interface UnitEnterprisesUnitList {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
extData: {
|
||||||
|
type: {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interface CkProjectListByType {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
extData: {
|
||||||
|
createTime: string
|
||||||
|
remark: string
|
||||||
|
totalScore: number
|
||||||
|
type: {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interface Item {
|
||||||
|
itemList: any[] // 根据实际情况调整类型
|
||||||
|
snowFlakeId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
export interface DataStatisticsRes {
|
||||||
|
/*企事业单位数量 */
|
||||||
|
enterprisesUnitCount: number;
|
||||||
|
|
||||||
|
/*服务项目数量 */
|
||||||
|
serviceProjectCount: number;
|
||||||
|
|
||||||
|
/*保安人员数量 */
|
||||||
|
securityUserCount: number;
|
||||||
|
|
||||||
|
/*无证保安人员数量 */
|
||||||
|
noCardSecurityUserCount: number;
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ export interface MyProjectList {
|
||||||
securityUnitId: string;
|
securityUnitId: string;
|
||||||
street?: string;
|
street?: string;
|
||||||
streetName?: string;
|
streetName?: string;
|
||||||
|
type?:any
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContactPersonInfo {
|
export interface ContactPersonInfo {
|
||||||
|
@ -30,24 +31,27 @@ export interface ServiceProjectList {
|
||||||
name?: string;
|
name?: string;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
securityUserTotal?: number;
|
securityUserTotal?: number;
|
||||||
|
securityUnitName?:string;
|
||||||
serviceArea?: number;
|
serviceArea?: number;
|
||||||
snowFlakeId?: string;
|
snowFlakeId?: string;
|
||||||
staffTotal?: number;
|
staffTotal?: number;
|
||||||
type?: string;
|
type?: any;
|
||||||
projectManagerMiniProgramUserInfo?: ProgramUserInfo
|
projectManagerMiniProgramUserInfo?: ProgramUserInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProgramUserInfo {
|
export interface ProgramUserInfo {
|
||||||
idCard: null
|
idCard?: null
|
||||||
name: string
|
name?: string
|
||||||
telephone: string
|
telephone?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServiceProjectSecurityUserPagerVo {
|
export interface ServiceProjectSecurityUserPagerVo {
|
||||||
createTime?: string;
|
createTime?: string;
|
||||||
dateOfBirth?: string;
|
dateOfBirth?: string;
|
||||||
homeAddress?: string;
|
homeAddress?: string;
|
||||||
idCard?: string;
|
idCard?: {
|
||||||
|
desensitizedValue?:string
|
||||||
|
originalValue?:string
|
||||||
|
};
|
||||||
name?: string;
|
name?: string;
|
||||||
nativePlace?: string;
|
nativePlace?: string;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
|
@ -59,3 +63,4 @@ export interface ServiceProjectSecurityUserPagerVo {
|
||||||
workPost?: string;
|
workPost?: string;
|
||||||
sex: BaseEnum<number>
|
sex: BaseEnum<number>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,27 @@ export interface SecurityUserFormParams {
|
||||||
snowFlakeId?: string;
|
snowFlakeId?: string;
|
||||||
securityUnitId: string;
|
securityUnitId: string;
|
||||||
serviceProjectId: string;
|
serviceProjectId: string;
|
||||||
name?: string;
|
name: string | undefined;
|
||||||
workPost?: string;
|
workPost?: string;
|
||||||
telephone?: string;
|
telephone: value | null;
|
||||||
sex: number;
|
sex: number;
|
||||||
nativePlace?: string;
|
nativePlace?: string;
|
||||||
idCard: string;
|
idCard: value | null;
|
||||||
dateOfBirth?: Date | null;
|
dateOfBirth?: Date | null;
|
||||||
securityNumber?: string;
|
securityNumber?: string;
|
||||||
|
photo?:string;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
|
noSecurityNumberDesc:string;
|
||||||
homeAddress?: string
|
homeAddress?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface value{
|
||||||
|
desensitizedValue?:string
|
||||||
|
originalValue?:string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface securityNumberByIdCard{
|
||||||
|
name: string | undefined
|
||||||
|
bayzh?: string
|
||||||
|
sfzhm?: string
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,22 @@ VITE_DROP_CONSOLE=false
|
||||||
VITE_APP_BASE_API=/api
|
VITE_APP_BASE_API=/api
|
||||||
# VITE_APP_PROXY_URL=http://localhost:8765
|
# VITE_APP_PROXY_URL=http://localhost:8765
|
||||||
VITE_APP_PROXY_URL=http://172.10.10.93:8765
|
VITE_APP_PROXY_URL=http://172.10.10.93:8765
|
||||||
|
#
|
||||||
|
|
||||||
# rsa 公钥
|
# rsa 公钥
|
||||||
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB
|
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB
|
||||||
|
|
||||||
|
# 高德 myx
|
||||||
|
# VITE_APP_GAODE_KEY=ca549d915cb38803582ca7e85c5f972c
|
||||||
|
# VITE_APP_GAODE_VERSION=2.0
|
||||||
|
# VITE_APP_SECURITY_JS_CODE=f464462874676b3f1469780a62e5b921
|
||||||
|
|
||||||
|
|
||||||
|
# 高德 lz
|
||||||
|
VITE_APP_GAODE_KEY=f379a3f860a68d7438526275d6a94b05
|
||||||
|
VITE_APP_GAODE_VERSION=2.0
|
||||||
|
VITE_APP_SECURITY_JS_CODE=432125a0f8d8cad2dac38b77d6f6728f
|
||||||
|
|
||||||
|
# minio
|
||||||
|
VITE_APP_MINIO_URL=http://118.253.177.137:9000
|
||||||
|
VITE_APP_MINIO_BUCKET=police-security-dev
|
|
@ -5,4 +5,15 @@ VITE_DROP_CONSOLE=true
|
||||||
|
|
||||||
# axios
|
# axios
|
||||||
VITE_APP_BASE_API=/api
|
VITE_APP_BASE_API=/api
|
||||||
VITE_APP_PROXY_URL=https://172.10.10.238:8765
|
VITE_APP_PROXY_URL=http://172.10.10.93:8765
|
||||||
|
# rsa 公钥
|
||||||
|
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpu1C3JHZ+Ng/eVVCZtwKsOZv9RktpAL13pKy4FoRHyNv2t8TPV2AMzLzfEzlWx001nBxyVxEMR2N9jAcqFLHv7r16ciOzbtzB9dky2G+bc9jIs4/EdVK5bAZcPRh5Jrb78sC9PHyR4AeceDyCIKHLUbWBJB4NTZE0s1Wh5kMynQIDAQAB
|
||||||
|
|
||||||
|
# 高德
|
||||||
|
VITE_APP_GAODE_KEY=f379a3f860a68d7438526275d6a94b05
|
||||||
|
VITE_APP_GAODE_VERSION=2.0
|
||||||
|
VITE_APP_SECURITY_JS_CODE=432125a0f8d8cad2dac38b77d6f6728f
|
||||||
|
|
||||||
|
# minio
|
||||||
|
VITE_APP_MINIO_URL=https://www.hnjinglian.cn:9002
|
||||||
|
VITE_APP_MINIO_BUCKET=police-security
|
|
@ -9,6 +9,8 @@ lerna-debug.log*
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
policeManagement
|
||||||
|
package-lock.json
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
||||||
AButton: typeof import('ant-design-vue/es')['Button']
|
AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
ACard: typeof import('ant-design-vue/es')['Card']
|
|
||||||
ACascader: typeof import('ant-design-vue/es')['Cascader']
|
ACascader: typeof import('ant-design-vue/es')['Cascader']
|
||||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||||
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
||||||
|
@ -17,10 +16,11 @@ declare module 'vue' {
|
||||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||||
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
|
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
|
||||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||||
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
AdministrativeDivisionTree: typeof import('./src/components/tree/AdministrativeDivisionTree.vue')['default']
|
||||||
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
||||||
AForm: typeof import('ant-design-vue/es')['Form']
|
AForm: typeof import('ant-design-vue/es')['Form']
|
||||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||||
|
AImage: typeof import('ant-design-vue/es')['Image']
|
||||||
AInput: typeof import('ant-design-vue/es')['Input']
|
AInput: typeof import('ant-design-vue/es')['Input']
|
||||||
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||||
|
@ -34,12 +34,11 @@ declare module 'vue' {
|
||||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
APopover: typeof import('ant-design-vue/es')['Popover']
|
APopover: typeof import('ant-design-vue/es')['Popover']
|
||||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||||
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
|
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
|
||||||
ARow: typeof import('ant-design-vue/es')['Row']
|
ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
|
||||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||||
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
||||||
|
@ -53,15 +52,14 @@ declare module 'vue' {
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
|
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
|
||||||
FormProMax: typeof import('./src/components/form/FormProMax.vue')['default']
|
FormProMax: typeof import('./src/components/form/FormProMax.vue')['default']
|
||||||
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
|
|
||||||
IconFont: typeof import('./src/components/iconfont/IconFont.vue')['default']
|
IconFont: typeof import('./src/components/iconfont/IconFont.vue')['default']
|
||||||
Layout: typeof import('./src/components/layout/layout.vue')['default']
|
Layout: typeof import('./src/components/layout/layout.vue')['default']
|
||||||
LayoutHeader: typeof import('./src/components/layout/header/LayoutHeader.vue')['default']
|
LayoutHeader: typeof import('./src/components/layout/header/LayoutHeader.vue')['default']
|
||||||
|
MapContainer: typeof import('./src/components/aMap/MapContainer.vue')['default']
|
||||||
MenuItem: typeof import('./src/components/layout/MenuItem.vue')['default']
|
MenuItem: typeof import('./src/components/layout/MenuItem.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
SingleImageFileUpload: typeof import('./src/components/upload/SingleImageFileUpload.vue')['default']
|
SingleImageFileUpload: typeof import('./src/components/upload/SingleImageFileUpload.vue')['default']
|
||||||
Sliber: typeof import('./src/components/layout/sliber/sliber.vue')['default']
|
|
||||||
SystemMenus: typeof import('./src/components/layout/SystemMenus.vue')['default']
|
SystemMenus: typeof import('./src/components/layout/SystemMenus.vue')['default']
|
||||||
TableProMax: typeof import('./src/components/table/TableProMax.vue')['default']
|
TableProMax: typeof import('./src/components/table/TableProMax.vue')['default']
|
||||||
TelephoneLogin: typeof import('./src/components/login/TelephoneLogin.vue')['default']
|
TelephoneLogin: typeof import('./src/components/login/TelephoneLogin.vue')['default']
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
declare module '*.vue' {
|
|
||||||
import type { DefineComponent } from 'vue'
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
|
||||||
const component: DefineComponent<{}, {}, any>
|
|
||||||
export default component
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
declare const __APP_ENV: ImportMetaEnv;
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
/**
|
|
||||||
* 全局返回
|
|
||||||
*/
|
|
||||||
interface JsonResult<T> {
|
|
||||||
code: number;
|
|
||||||
message: string;
|
|
||||||
data?: T;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface SecurityUnitPagerQueryParams {
|
|
||||||
/** 名称 **/
|
|
||||||
name?: string;
|
|
||||||
/** 社会编码 **/
|
|
||||||
socialCode?: string;
|
|
||||||
/** 行政区划编码 **/
|
|
||||||
administrativeDivisionCodes?: string[];
|
|
||||||
/** 是否启用 **/
|
|
||||||
isEnable?: number;
|
|
||||||
/** 审核状态 **/
|
|
||||||
checkStatus?: number;
|
|
||||||
}
|
|
||||||
interface BaseEnum<T> {
|
|
||||||
value: T;
|
|
||||||
label: string
|
|
||||||
}
|
|
||||||
class TreeNodeVo<T, E = Record<string, any>> {
|
|
||||||
value: T;
|
|
||||||
parentValue: T;
|
|
||||||
label: string;
|
|
||||||
orderIndex?: number;
|
|
||||||
children?: TreeNodeVo<T>[]
|
|
||||||
extData?: E;
|
|
||||||
}
|
|
||||||
declare interface Grid {
|
|
||||||
//栅格占据的列数
|
|
||||||
span?: number;
|
|
||||||
//栅格左侧的间隔格数
|
|
||||||
offset?: number;
|
|
||||||
//栅格向右移动格数
|
|
||||||
push?: number;
|
|
||||||
//栅格向左移动格数
|
|
||||||
pull?: number;
|
|
||||||
//<768px 响应式栅格数或者栅格属性对象
|
|
||||||
xs?: number;
|
|
||||||
//≥768px 响应式栅格数或者栅格属性对象
|
|
||||||
sm?: number;
|
|
||||||
//≥992px 响应式栅格数或者栅格属性对象
|
|
||||||
md?: number;
|
|
||||||
//≥1200px 响应式栅格数或者栅格属性对象
|
|
||||||
lg?: number;
|
|
||||||
//≥1920px 响应式栅格数或者栅格属性对象
|
|
||||||
xl?: number;
|
|
||||||
}
|
|
||||||
interface dataStatus {
|
|
||||||
account: string;
|
|
||||||
password: string;
|
|
||||||
remark: string;
|
|
||||||
checkStatus: {
|
|
||||||
extData: {
|
|
||||||
color: string;
|
|
||||||
};
|
|
||||||
label: string;
|
|
||||||
value: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
class SelectNodeVo<T, E = Record<string, any>> {
|
|
||||||
value: T;
|
|
||||||
label: string;
|
|
||||||
options?: SelectNodeVo<T>[]
|
|
||||||
orderIndex?: number;
|
|
||||||
disabled?: boolean;
|
|
||||||
extData?: E
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ExtData {
|
|
||||||
color?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Option {
|
|
||||||
label: string;
|
|
||||||
value: string | number;
|
|
||||||
extData?: ExtData | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OptionsResponse {
|
|
||||||
IsEnable: Option[];
|
|
||||||
IsOrNot: Option[];
|
|
||||||
Sex: Option[];
|
|
||||||
CheckStatus: Option[];
|
|
||||||
ServiceProjectType: Option[];
|
|
||||||
DeleteFlag: Option[];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<script type="module" src="/src/assets/iconfont/iconfont.js"></script>
|
<script type="module" src="/src/assets/iconfont/iconfont.js"></script>
|
||||||
|
|
||||||
<title>Vite + Vue + TS</title>
|
<title>公安后台</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -6,30 +6,36 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc -b && vite build",
|
"build": "vite build --mode production",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||||
|
"@vueuse/core": "^11.2.0",
|
||||||
"ant-design-vue": "^4.2.3",
|
"ant-design-vue": "^4.2.3",
|
||||||
"axios": "^1.7.5",
|
"axios": "^1.7.5",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"pinia": "^2.2.2",
|
"pinia": "^2.2.2",
|
||||||
"pinia-plugin-persistedstate": "^3.2.0",
|
"pinia-plugin-persistedstate": "^3.2.0",
|
||||||
"vue-component-type-helpers": "^2.1.2",
|
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.77.8",
|
||||||
"vue": "^3.4.37",
|
"vue": "^3.4.37",
|
||||||
|
"vue-component-type-helpers": "^2.1.2",
|
||||||
"vue-router": "4",
|
"vue-router": "4",
|
||||||
"vue-uuid": "^3.0.0"
|
"vue-uuid": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@amap/amap-jsapi-types": "^0.0.15",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.5.1",
|
"@types/node": "^22.5.1",
|
||||||
|
"@types/react": "^18.3.12",
|
||||||
"@vitejs/plugin-vue": "^5.1.2",
|
"@vitejs/plugin-vue": "^5.1.2",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
"@vitejs/plugin-vue-jsx": "^4.1.0",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"postcss": "^8.4.41",
|
"postcss": "^8.4.41",
|
||||||
"tailwindcss": "^3.4.10",
|
"tailwindcss": "^3.4.10",
|
||||||
|
"terser": "^5.36.0",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"unplugin-vue-components": "^0.27.4",
|
"unplugin-vue-components": "^0.27.4",
|
||||||
"vite": "^5.4.1",
|
"vite": "^5.4.1",
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
/* 扩展ant design pro按钮组件颜色 */
|
||||||
|
$--my-antd-important: !important;
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #F5222D;
|
||||||
|
border-color: #F5222D;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #ff4d4f $--my-antd-important;
|
||||||
|
border-color: #ff4d4f $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #cf1322 $--my-antd-important;
|
||||||
|
border-color: #cf1322 $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-volcano {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #FA541C;
|
||||||
|
border-color: #FA541C;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #ff7a45 $--my-antd-important;
|
||||||
|
border-color: #ff7a45 $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #d4380d $--my-antd-important;
|
||||||
|
border-color: #d4380d $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-warn {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #FAAD14;
|
||||||
|
border-color: #FAAD14;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #ffc53d $--my-antd-important;
|
||||||
|
border-color: #ffc53d $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #d48806 $--my-antd-important;
|
||||||
|
border-color: #d48806 $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #52C41A;
|
||||||
|
border-color: #52C41A;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #73d13d $--my-antd-important;
|
||||||
|
border-color: #73d13d $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #389e0d $--my-antd-important;
|
||||||
|
border-color: #389e0d $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-color-cyan {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #13C2C2;
|
||||||
|
border-color: #13C2C2;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #36cfc9 $--my-antd-important;
|
||||||
|
border-color: #36cfc9 $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #08979c $--my-antd-important;
|
||||||
|
border-color: #08979c $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-daybreak {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #1890FF;
|
||||||
|
border-color: #1890FF;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #096dd9 $--my-antd-important;
|
||||||
|
border-color: #096dd9 $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #40a9ff $--my-antd-important;
|
||||||
|
border-color: #40a9ff $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-color-geekblue {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #2F54EB;
|
||||||
|
border-color: #2F54EB;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #1d39c4 $--my-antd-important;
|
||||||
|
border-color: #1d39c4 $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #597ef7 $--my-antd-important;
|
||||||
|
border-color: #597ef7 $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-purple {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #722ED1;
|
||||||
|
border-color: #722ED1;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #9254de $--my-antd-important;
|
||||||
|
border-color: #9254de $--my-antd-important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: #ffffff $--my-antd-important;
|
||||||
|
background-color: #531dab $--my-antd-important;
|
||||||
|
border-color: #531dab $--my-antd-important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row-warn td {
|
||||||
|
background-color: #fefca6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row-danger td {
|
||||||
|
background-color: #f79988;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row-success td {
|
||||||
|
background-color: #b6fcbe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-summary td {
|
||||||
|
background: #edeff6;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
<template>
|
||||||
|
<div :id="mapId" class="mapContainer">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, shallowRef } from 'vue'
|
||||||
|
import { initMap } from '@/utils/aMapUtil'
|
||||||
|
import { MapContainerProps, MapPlugins } from '@/types/components/map/index.ts'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<MapContainerProps>(), {
|
||||||
|
plugins: (): MapPlugins[] => {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
mapOptions: (): AMap.MapOptions => {
|
||||||
|
return {
|
||||||
|
// 是否为3D地图模式
|
||||||
|
viewMode: '3D',
|
||||||
|
// 初始化地图级别
|
||||||
|
zoom: 11,
|
||||||
|
mapStyle: 'amap://styles/darkblue',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapId = 'mapContainer'
|
||||||
|
const map = shallowRef<AMap.Map>(null)
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
mapInstance: map,
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initMap(props.plugins).then((AMap) => {
|
||||||
|
map.value = new AMap.Map(mapId, props.mapOptions)
|
||||||
|
props.initCallback && props.initCallback(map.value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
map.value?.destroy()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
#mapContainer {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -67,6 +67,7 @@
|
||||||
:allowClear="item.componentsProps?.allowClear ?? true"
|
:allowClear="item.componentsProps?.allowClear ?? true"
|
||||||
:options="item.options"
|
:options="item.options"
|
||||||
/>
|
/>
|
||||||
|
<administrative-division-tree-comp v-else-if="item.type === 'administrativeDivisionTree'" style="width: 100%" v-model:value="modelValue[field]" v-bind="item.componentsProps" />
|
||||||
<a-range-picker
|
<a-range-picker
|
||||||
v-else-if="item.type === 'rangePicker'"
|
v-else-if="item.type === 'rangePicker'"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -111,10 +112,14 @@
|
||||||
|
|
||||||
<script setup lang="ts" generic="T extends Record<string,any>">
|
<script setup lang="ts" generic="T extends Record<string,any>">
|
||||||
import { FormInstance } from 'ant-design-vue'
|
import { FormInstance } from 'ant-design-vue'
|
||||||
import { ref } from 'vue'
|
import { defineAsyncComponent, ref } from 'vue'
|
||||||
import { FormExpose } from 'ant-design-vue/es/form/Form'
|
import { FormExpose } from 'ant-design-vue/es/form/Form'
|
||||||
import { QuestionCircleOutlined } from '@ant-design/icons-vue'
|
import { QuestionCircleOutlined } from '@ant-design/icons-vue'
|
||||||
import { FormProMaxItemOptions, FormProMaxItemProps, FormProMaxProps } from '@/types/components/form/index.ts'
|
import { FormProMaxItemOptions, FormProMaxItemProps, FormProMaxProps } from '@/types/components/form/index.ts'
|
||||||
|
import { ComponentProps } from 'vue-component-type-helpers'
|
||||||
|
import AdministrativeDivisionTree from '@/components/tree/AdministrativeDivisionTree.vue'
|
||||||
|
|
||||||
|
const AdministrativeDivisionTreeComp: ComponentProps<typeof AdministrativeDivisionTree> = defineAsyncComponent(() => import('@/components/tree/AdministrativeDivisionTree.vue'))
|
||||||
|
|
||||||
const modelValue = defineModel<T>('value', {
|
const modelValue = defineModel<T>('value', {
|
||||||
default: {},
|
default: {},
|
||||||
|
@ -147,7 +152,7 @@ const props = withDefaults(defineProps<FormProMaxProps<T>>(), {
|
||||||
scrollToFirstError: undefined,
|
scrollToFirstError: undefined,
|
||||||
validateOnRuleChange: undefined,
|
validateOnRuleChange: undefined,
|
||||||
})
|
})
|
||||||
console.log(props)
|
|
||||||
const formProMaxRef = ref<FormInstance>(null!)
|
const formProMaxRef = ref<FormInstance>(null!)
|
||||||
|
|
||||||
const getResponsive = (item: FormProMaxItemProps): Grid => {
|
const getResponsive = (item: FormProMaxItemProps): Grid => {
|
||||||
|
|
|
@ -144,7 +144,7 @@ const props = withDefaults(defineProps<TableProMaxProps<T, P>>(), {
|
||||||
showExpandColumn: undefined,
|
showExpandColumn: undefined,
|
||||||
sticky: undefined,
|
sticky: undefined,
|
||||||
})
|
})
|
||||||
console.log(props)
|
// console.log(props)
|
||||||
|
|
||||||
const slots = defineSlots<TableProMaxSlots<T>>()
|
const slots = defineSlots<TableProMaxSlots<T>>()
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ const {
|
||||||
props.dataCallback,
|
props.dataCallback,
|
||||||
props.requestError
|
props.requestError
|
||||||
)
|
)
|
||||||
console.log('pageParams', pageParams)
|
// console.log('pageParams', pageParams)
|
||||||
|
|
||||||
onMounted(() => props.requestAuto && requestGetTableData(true))
|
onMounted(() => props.requestAuto && requestGetTableData(true))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<template>
|
||||||
|
<a-cascader
|
||||||
|
v-model:value="modelValue"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:change-on-select="changeOnSelect"
|
||||||
|
:options="administrativeDivisionTree"
|
||||||
|
:load-data="loadData"
|
||||||
|
:allow-clear="allowClear"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import api from "@/axios";
|
||||||
|
import {onMounted, ref} from "vue";
|
||||||
|
import {CascaderProps} from "ant-design-vue";
|
||||||
|
import {isEmpty} from "lodash-es";
|
||||||
|
|
||||||
|
withDefaults(defineProps<{
|
||||||
|
placeholder?: string,
|
||||||
|
changeOnSelect?: boolean
|
||||||
|
allowClear?: boolean
|
||||||
|
}>(), {
|
||||||
|
placeholder: '请选择行政区划',
|
||||||
|
changeOnSelect: true,
|
||||||
|
allowClear: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const modelValue = defineModel('value', {
|
||||||
|
default: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const administrativeDivisionTree = ref<TreeNodeVo<string>[]>([])
|
||||||
|
|
||||||
|
const loadData: CascaderProps['loadData'] = selectedOptions => {
|
||||||
|
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||||
|
targetOption.loading = true;
|
||||||
|
administrativeDivisionByParentCode(targetOption.value as string).then(data => {
|
||||||
|
targetOption.loading = false
|
||||||
|
targetOption.children = data
|
||||||
|
administrativeDivisionTree.value = [...administrativeDivisionTree.value]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据父级编码查询行政区划
|
||||||
|
* @param code
|
||||||
|
*/
|
||||||
|
const administrativeDivisionByParentCode = async (code: string = '0'): Promise<TreeNodeVo<string>[]> => {
|
||||||
|
const resp = await api.get<TreeNodeVo<string>[]>('/common/administrativeDivisionByParentCode', {
|
||||||
|
parentCode: code
|
||||||
|
})
|
||||||
|
//解决点击无加载提示
|
||||||
|
return resp.data.map(item => {
|
||||||
|
delete item.children
|
||||||
|
return item
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
administrativeDivisionTree.value = await administrativeDivisionByParentCode()
|
||||||
|
if (!isEmpty(modelValue.value)) {
|
||||||
|
const ps = modelValue.value.map(code => administrativeDivisionByParentCode(code))
|
||||||
|
Promise.all(ps).then(data => {
|
||||||
|
let i = 0;
|
||||||
|
const deepChildren = (treeData: TreeNodeVo<string>[]) => {
|
||||||
|
treeData.forEach(item => {
|
||||||
|
if (item.value === modelValue.value[i]) {
|
||||||
|
item.children = data[i]
|
||||||
|
i++;
|
||||||
|
deepChildren(item.children)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
deepChildren(administrativeDivisionTree.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,8 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="simpleUploadDiv">
|
<div class="simpleUploadDiv">
|
||||||
<a-progress v-if="uploading" type="circle" :percent="percent" />
|
<a-progress v-if="uploading" type="circle" :percent="percent" />
|
||||||
<a-image height="80%" v-else :src="minioBaseUrl + modelValue" alt="avatar" />
|
<!-- height="80%" width="80%" -->
|
||||||
<a-button class="btn-success" @click="selectFile">{{ btnLabel }}</a-button>
|
<a-image v-else :src="minioBaseUrl + modelValue" alt="avatar" />
|
||||||
|
<a-button style="margin-top: 4px" class="btn-success" @click="selectFile">{{ btnLabel }}</a-button>
|
||||||
<input id="myFileInput" type="file" style="display: none" />
|
<input id="myFileInput" type="file" style="display: none" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
// global.d.ts不能出现 export 关键字否则这个文件会失效
|
||||||
|
declare const __APP_ENV: ImportMetaEnv;
|
||||||
|
class TreeNodeVo<T, E = Record<string, any>> {
|
||||||
|
value: T;
|
||||||
|
parentValue: T;
|
||||||
|
label: string;
|
||||||
|
orderIndex?: number;
|
||||||
|
children?: TreeNodeVo<T>[]
|
||||||
|
extData?: E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局返回
|
||||||
|
*/
|
||||||
|
interface JsonResult<T> {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
data?: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface SecurityUnitPagerQueryParams {
|
||||||
|
/** 名称 **/
|
||||||
|
name?: string;
|
||||||
|
/** 社会编码 **/
|
||||||
|
socialCode?: string;
|
||||||
|
/** 行政区划编码 **/
|
||||||
|
administrativeDivisionCodes?: string[];
|
||||||
|
/** 是否启用 **/
|
||||||
|
isEnable?: number;
|
||||||
|
/** 审核状态 **/
|
||||||
|
checkStatus?: number;
|
||||||
|
}
|
||||||
|
interface BaseEnum<T> {
|
||||||
|
value: T;
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Grid {
|
||||||
|
//栅格占据的列数
|
||||||
|
span?: number;
|
||||||
|
//栅格左侧的间隔格数
|
||||||
|
offset?: number;
|
||||||
|
//栅格向右移动格数
|
||||||
|
push?: number;
|
||||||
|
//栅格向左移动格数
|
||||||
|
pull?: number;
|
||||||
|
//<768px 响应式栅格数或者栅格属性对象
|
||||||
|
xs?: number;
|
||||||
|
//≥768px 响应式栅格数或者栅格属性对象
|
||||||
|
sm?: number;
|
||||||
|
//≥992px 响应式栅格数或者栅格属性对象
|
||||||
|
md?: number;
|
||||||
|
//≥1200px 响应式栅格数或者栅格属性对象
|
||||||
|
lg?: number;
|
||||||
|
//≥1920px 响应式栅格数或者栅格属性对象
|
||||||
|
xl?: number;
|
||||||
|
}
|
||||||
|
interface dataStatus {
|
||||||
|
account: string;
|
||||||
|
password: string;
|
||||||
|
remark: string;
|
||||||
|
checkStatus: {
|
||||||
|
extData: {
|
||||||
|
color: string;
|
||||||
|
};
|
||||||
|
label: string;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
class SelectNodeVo<T, E = Record<string, any>> {
|
||||||
|
value: T;
|
||||||
|
label: string;
|
||||||
|
options?: SelectNodeVo<T>[]
|
||||||
|
orderIndex?: number;
|
||||||
|
disabled?: boolean;
|
||||||
|
extData?: E
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExtData {
|
||||||
|
color?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
extData?: ExtData | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OptionsResponse {
|
||||||
|
IsEnable: Option[];
|
||||||
|
IsOrNot: Option[];
|
||||||
|
Sex: Option[];
|
||||||
|
CheckStatus: Option[];
|
||||||
|
ServiceProjectType: Option[];
|
||||||
|
DeleteFlag: Option[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TypeEnum<T> {
|
||||||
|
value: string;
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,15 @@ import {createApp} from 'vue'
|
||||||
import App from '@/App.vue'
|
import App from '@/App.vue'
|
||||||
import '@/reset.css'
|
import '@/reset.css'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
// 公共样式
|
|
||||||
import '@/assets/scss/common.scss'
|
import '@/assets/scss/common.scss'
|
||||||
// iconfont css
|
import '@/assets/scss/myAntD.scss'
|
||||||
import "@/assets/iconfont/iconfont.css";
|
import "@/assets/iconfont/iconfont.css";
|
||||||
// vue Router
|
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
// pinia stores
|
|
||||||
import pinia from "@/stores";
|
import pinia from "@/stores";
|
||||||
|
|
||||||
const vueApp = createApp(App);
|
const vueApp = createApp(App);
|
||||||
import { initEnums } from "@/config/dict.ts";
|
import { initEnums } from "@/config/dict.ts";
|
||||||
|
//高德类型声明文件
|
||||||
|
import "@amap/amap-jsapi-types";
|
||||||
initEnums()
|
initEnums()
|
||||||
vueApp
|
vueApp
|
||||||
.use(router)
|
.use(router)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { ROUTER_WHITE_LIST } from "@/config";
|
||||||
* createWebHashHistory: 路径带#号 这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,影响SEO
|
* createWebHashHistory: 路径带#号 这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,影响SEO
|
||||||
*/
|
*/
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory('/policeManagement/'),
|
||||||
routes: [...staticRouter],
|
routes: [...staticRouter],
|
||||||
strict: false,
|
strict: false,
|
||||||
scrollBehavior: () => ({ left: 0, top: 0 })
|
scrollBehavior: () => ({ left: 0, top: 0 })
|
||||||
|
|
|
@ -81,7 +81,21 @@ export const staticRouter: RouteRecordRaw[] =
|
||||||
keepalive: true
|
keepalive: true
|
||||||
},
|
},
|
||||||
component: () => import('@/views/query/publicUnit.vue')
|
component: () => import('@/views/query/publicUnit.vue')
|
||||||
|
// component: () => import('@/views/query/index.tsx')
|
||||||
|
// component: () => import('@/views/query/EnterprisesUnit')
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'assessment-record', // 这里使用相对路径而不是 '/register'
|
||||||
|
name: 'assessment-record',
|
||||||
|
meta: {
|
||||||
|
|
||||||
|
title: '考核记录',
|
||||||
|
keepalive: true
|
||||||
|
},
|
||||||
|
component: () => import('@/views/query/assessmentRecord.vue')
|
||||||
|
}
|
||||||
// {
|
// {
|
||||||
// path: 'weapp-user', // 这里使用相对路径而不是 '/register'
|
// path: 'weapp-user', // 这里使用相对路径而不是 '/register'
|
||||||
// name: 'weapp-user',
|
// name: 'weapp-user',
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
} from "ant-design-vue";
|
} from "ant-design-vue";
|
||||||
import { Ref, UnwrapRef, VNode } from "vue";
|
import { Ref, UnwrapRef, VNode } from "vue";
|
||||||
import { ComponentProps } from "vue-component-type-helpers";
|
import { ComponentProps } from "vue-component-type-helpers";
|
||||||
|
import AdministrativeDivisionTree from "@/components/tree/AdministrativeDivisionTree.vue";
|
||||||
|
|
||||||
type FormProMaxItemType =
|
type FormProMaxItemType =
|
||||||
| 'custom'
|
| 'custom'
|
||||||
|
@ -32,7 +33,8 @@ type FormProMaxItemType =
|
||||||
| 'datePicker'
|
| 'datePicker'
|
||||||
| 'rangePicker'
|
| 'rangePicker'
|
||||||
| 'timeRangePicker'
|
| 'timeRangePicker'
|
||||||
| 'timePicker';
|
| 'timePicker'
|
||||||
|
| 'administrativeDivisionTree'
|
||||||
|
|
||||||
interface FormProMaxItemCommonProps extends ComponentProps<typeof FormItem> {
|
interface FormProMaxItemCommonProps extends ComponentProps<typeof FormItem> {
|
||||||
label?: string,
|
label?: string,
|
||||||
|
@ -64,6 +66,7 @@ export type FormProMaxItemOptions<T> = {
|
||||||
| FormProMaxItemProps<'rangePicker', ComponentProps<typeof RangePicker>>
|
| FormProMaxItemProps<'rangePicker', ComponentProps<typeof RangePicker>>
|
||||||
| FormProMaxItemProps<'timeRangePicker', ComponentProps<typeof TimeRangePicker>>
|
| FormProMaxItemProps<'timeRangePicker', ComponentProps<typeof TimeRangePicker>>
|
||||||
| FormProMaxItemProps<'timePicker', ComponentProps<typeof TimePicker>>
|
| FormProMaxItemProps<'timePicker', ComponentProps<typeof TimePicker>>
|
||||||
|
| FormProMaxItemProps<'administrativeDivisionTree', ComponentProps<typeof AdministrativeDivisionTree>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormProMaxProps<T = {}> extends FormProps {
|
export interface FormProMaxProps<T = {}> extends FormProps {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* 高德支持的插件列表
|
||||||
|
* @link https://lbs.amap.com/api/javascript-api-v2/guide/abc/plugins-list
|
||||||
|
*/
|
||||||
|
export type MapPlugins =
|
||||||
|
'AMap.ElasticMarker'
|
||||||
|
| 'AMap.ToolBar'
|
||||||
|
| 'AMap.Scale'
|
||||||
|
| 'AMap.HawkEye'
|
||||||
|
| 'AMap.ControlBar'
|
||||||
|
| 'AMap.MapType'
|
||||||
|
| 'AMap.Geolocation'
|
||||||
|
| 'AMap.AutoComplete'
|
||||||
|
| 'AMap.PlaceSearch'
|
||||||
|
| 'AMap.DistrictSearch'
|
||||||
|
| 'AMap.LineSearch'
|
||||||
|
| 'AMap.StationSearch'
|
||||||
|
| 'AMap.Driving'
|
||||||
|
| 'AMap.TruckDriving'
|
||||||
|
| 'AMap.Transfer'
|
||||||
|
| 'AMap.Walking'
|
||||||
|
| 'AMap.Riding'
|
||||||
|
| 'AMap.DragRoute'
|
||||||
|
| 'AMap.Geocoder'
|
||||||
|
| 'AMap.CitySearch'
|
||||||
|
| 'AMap.IndoorMap'
|
||||||
|
| 'AMap.MouseTool'
|
||||||
|
| 'AMap.CircleEditor'
|
||||||
|
| 'AMap.PolygonEditor'
|
||||||
|
| 'AMap.PolylineEditor'
|
||||||
|
| 'AMap.RectangleEditor'
|
||||||
|
| 'AMap.EllipseEditor'
|
||||||
|
| 'AMap.BezierCurveEditor'
|
||||||
|
| 'AMap.MarkerCluster'
|
||||||
|
| 'AMap.RangingTool'
|
||||||
|
| 'AMap.CloudDataSearch'
|
||||||
|
| 'AMap.Weather'
|
||||||
|
| 'AMap.HeatMap'
|
||||||
|
|
||||||
|
export interface MapContainerProps {
|
||||||
|
plugins?: MapPlugins[],
|
||||||
|
initCallback?: (map: AMap.Map) => void,
|
||||||
|
mapOptions?: AMap.MapOptions
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
import {BaseTableRowRecord} from "@/types/components/table";
|
||||||
|
import {BaseEnum} from "../../../global";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface AssessmentRecordPagerVo extends BaseTableRowRecord {
|
||||||
|
/** 企事业单位名称 **/
|
||||||
|
enterprisesUnitName: string;
|
||||||
|
/** 考核项目名称 **/
|
||||||
|
ckProjectName: string;
|
||||||
|
/** 考核项目总分 **/
|
||||||
|
totalScore: number;
|
||||||
|
/** 考核项目类型 **/
|
||||||
|
type: BaseEnum<string>;
|
||||||
|
/** 考核项目备注 **/
|
||||||
|
ckProjectRemark: string;
|
||||||
|
/** 公安单位名称 **/
|
||||||
|
policeUnitName: string;
|
||||||
|
/** 考核人员签字 **/
|
||||||
|
assessmentUserSignature: string;
|
||||||
|
/** 被考核单位人员签字 **/
|
||||||
|
byAssessmentEnterprisesUnitUserSignature: string;
|
||||||
|
/** 考核备注 **/
|
||||||
|
remark: string;
|
||||||
|
/** 总扣分 **/
|
||||||
|
deductionPointsTotal: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface AssessmentRecordPagerQueryParams {
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeductedDetailRes {
|
||||||
|
/*考核分组id */
|
||||||
|
ckGroupId: number;
|
||||||
|
groupRowSpan: number;
|
||||||
|
/*考核分组名字 */
|
||||||
|
groupName: string;
|
||||||
|
/*考核分组总分 */
|
||||||
|
groupTotalScore: number;
|
||||||
|
/*考核分组备注 */
|
||||||
|
groupRemark: string;
|
||||||
|
/*考核项id */
|
||||||
|
ckItemId: number;
|
||||||
|
itemRowSpan: number;
|
||||||
|
/*考核项名字 */
|
||||||
|
itemName: string;
|
||||||
|
/*组件类型,可用值:RADIO,MULTIPLE */
|
||||||
|
itemType: BaseEnum<string>;
|
||||||
|
/*考核项备注 */
|
||||||
|
itemRemark: string;
|
||||||
|
/*考核标准id */
|
||||||
|
ckStandardId: number;
|
||||||
|
/*考核标准 */
|
||||||
|
standardName: string;
|
||||||
|
/*扣分数 */
|
||||||
|
deductionPoints: Record<string, unknown>;
|
||||||
|
/*是否选中 */
|
||||||
|
isSelected: boolean;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { BaseTableRowRecord } from "@/types/components/table";
|
||||||
|
|
||||||
|
export interface serviceProjectSaveOrUpdateParams_ extends BaseTableRowRecord {
|
||||||
|
snowFlakeId: string
|
||||||
|
enterprisesUnitId: string,
|
||||||
|
enterprisesUnitName: string,
|
||||||
|
projectManagerMiniProgramUserId: string,
|
||||||
|
projectManagerMiniProgramUserName: string,
|
||||||
|
name: string,
|
||||||
|
type: TypeEnum<string>,
|
||||||
|
twoType: BaseEnum<any>,
|
||||||
|
outsourceName: string,
|
||||||
|
isFiling: BaseEnum<number>,
|
||||||
|
idNumber: string,
|
||||||
|
serviceArea: number,
|
||||||
|
buildingTotal: number,
|
||||||
|
houseTotal: number,
|
||||||
|
staffTotal: number,
|
||||||
|
securityUserTotal: number,
|
||||||
|
remark: string,
|
||||||
|
createUserName: string,
|
||||||
|
createTime: string,
|
||||||
|
enterprisesUnitAdministrativeDivisionCodes: Record<string, any>
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
import { BaseTableRowRecord } from "@/types/components/table";
|
||||||
|
|
||||||
|
export interface PoliceUnitPagerQueryParams {
|
||||||
|
/** 名称 **/
|
||||||
|
name?: string;
|
||||||
|
/** 代码 **/
|
||||||
|
code?: string;
|
||||||
|
/** 行政区划 **/
|
||||||
|
administrativeDivisionCodes?: string[];
|
||||||
|
/** 是否启用 **/
|
||||||
|
isEnable?: BaseEnum<number>;
|
||||||
|
/** 审核状态 **/
|
||||||
|
checkStatus?: BaseEnum<number>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PoliceUnitPagerVo extends BaseTableRowRecord {
|
||||||
|
|
||||||
|
sex: { label: string }
|
||||||
|
/** 名称 **/
|
||||||
|
name?: string;
|
||||||
|
/** 代码 **/
|
||||||
|
code?: string;
|
||||||
|
/** 省编码 **/
|
||||||
|
province?: string;
|
||||||
|
/** 省名字 **/
|
||||||
|
provinceName?: string;
|
||||||
|
/** 市编码 **/
|
||||||
|
city?: string;
|
||||||
|
/** 市名字 **/
|
||||||
|
cityName?: string;
|
||||||
|
/** 区/县编码 **/
|
||||||
|
districts?: string;
|
||||||
|
/** 区/县名字 **/
|
||||||
|
districtsName?: string;
|
||||||
|
/** 街道编码 **/
|
||||||
|
street?: string;
|
||||||
|
/** 街道编码 **/
|
||||||
|
streetName?: string;
|
||||||
|
/** 详细地址 **/
|
||||||
|
address?: string;
|
||||||
|
/** 联系人 **/
|
||||||
|
contactPersonInfo?: {
|
||||||
|
name: string;
|
||||||
|
telephone: string;
|
||||||
|
};
|
||||||
|
/** 是否启用 **/
|
||||||
|
isEnable?: BaseEnum<number>;
|
||||||
|
/** 审核状态 **/
|
||||||
|
checkStatus?: BaseEnum<number>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnterprisesUnitPagerQueryParams {
|
||||||
|
/** 公安单位id **/
|
||||||
|
policeUnitId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnterprisesUnitPagerVo extends BaseTableRowRecord {
|
||||||
|
sex: { label: string }
|
||||||
|
/** 名字 **/
|
||||||
|
name?: string;
|
||||||
|
type: BaseEnum<string>
|
||||||
|
/** 公安单位id **/
|
||||||
|
policeUnitId: string;
|
||||||
|
/** 省编码 **/
|
||||||
|
province?: string;
|
||||||
|
/** 省名称 **/
|
||||||
|
provinceName?: string;
|
||||||
|
/** 市编码 **/
|
||||||
|
city?: string;
|
||||||
|
/** 市名称 **/
|
||||||
|
cityName?: string;
|
||||||
|
/** 区编码 **/
|
||||||
|
districts?: string;
|
||||||
|
/** 区名称 **/
|
||||||
|
districtsName?: string;
|
||||||
|
/** 街编码 **/
|
||||||
|
street?: string;
|
||||||
|
/** 街名称 **/
|
||||||
|
streetName?: string;
|
||||||
|
/** 地址 **/
|
||||||
|
address?: string;
|
||||||
|
point: [number, number]
|
||||||
|
/** 联系方式 **/
|
||||||
|
contactPersonInfo?: {
|
||||||
|
name: string;
|
||||||
|
telephone: string;
|
||||||
|
};
|
||||||
|
/** 备注 **/
|
||||||
|
remark?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface EnterprisesUnitSaveOrUpdateParams {
|
||||||
|
/** id **/
|
||||||
|
snowFlakeId?: string;
|
||||||
|
|
||||||
|
/** 公安单位id **/
|
||||||
|
policeUnitId: string;
|
||||||
|
/** 名称 **/
|
||||||
|
name: string;
|
||||||
|
/** 类型 **/
|
||||||
|
type: string;
|
||||||
|
/** 行政区划编码 **/
|
||||||
|
administrativeDivisionCodes: string[];
|
||||||
|
/** 详细地址 **/
|
||||||
|
address?: string;
|
||||||
|
point?: [number, number]
|
||||||
|
/** 联系人 **/
|
||||||
|
contactPersonInfo?: {
|
||||||
|
name: string;
|
||||||
|
telephone: string;
|
||||||
|
};
|
||||||
|
/** 备注 **/
|
||||||
|
remark?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface securityUnitIdListParams {
|
||||||
|
snowFlakeId?: string;
|
||||||
|
serviceProjectId?: string;
|
||||||
|
securityUnitId?: string;
|
||||||
|
name?: string;
|
||||||
|
remark?: string;
|
||||||
|
photo?: string;
|
||||||
|
telephone?: string;
|
||||||
|
workPost?: string;
|
||||||
|
sex?: string;
|
||||||
|
nativePlace?: string;
|
||||||
|
idCard?: string;
|
||||||
|
dateOfBirth?: string;
|
||||||
|
securityNumber?: string;
|
||||||
|
noSecurityNumberDesc?: string;
|
||||||
|
homeAddress?: string;
|
||||||
|
}
|
||||||
|
export interface securityUnitIdListPagerVo {
|
||||||
|
snowFlakeId?: string;
|
||||||
|
serviceProjectId?: string;
|
||||||
|
securityUnitId?: string;
|
||||||
|
name?: string;
|
||||||
|
remark?: string;
|
||||||
|
photo?: string;
|
||||||
|
telephone?: {
|
||||||
|
desensitizedValue?: string;
|
||||||
|
originalValue?: string;
|
||||||
|
};
|
||||||
|
workPost?: string;
|
||||||
|
sex?: {
|
||||||
|
label?: string;
|
||||||
|
value: number | string
|
||||||
|
};
|
||||||
|
nativePlace?: string;
|
||||||
|
idCard?: {
|
||||||
|
desensitizedValue?: string;
|
||||||
|
originalValue?: string;
|
||||||
|
};
|
||||||
|
dateOfBirth?: string;
|
||||||
|
securityNumber?: string;
|
||||||
|
noSecurityNumberDesc?: string;
|
||||||
|
homeAddress?: string;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||||
|
import { MapPlugins } from "@/types/components/map/index";
|
||||||
|
|
||||||
|
export const initMap = (plugins?: MapPlugins[]): Promise<typeof AMap> => new Promise((resolve, reject) => {
|
||||||
|
//@ts-ignore
|
||||||
|
window._AMapSecurityConfig = {
|
||||||
|
securityJsCode: __APP_ENV.VITE_APP_SECURITY_JS_CODE
|
||||||
|
}
|
||||||
|
AMapLoader.load({
|
||||||
|
key: __APP_ENV.VITE_APP_GAODE_KEY,
|
||||||
|
version: __APP_ENV.VITE_APP_GAODE_VERSION,
|
||||||
|
plugins
|
||||||
|
}).then((aMap: typeof AMap) => {
|
||||||
|
resolve(aMap)
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,4 +1,4 @@
|
||||||
<template><div>111111</div></template>
|
<template><div>公安后台</div></template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
import api from '@/axios'
|
||||||
|
import { AssessmentRecordPagerVo, DeductedDetailRes } from '@/types/views/assessmentRecord.ts'
|
||||||
|
import { ColumnsType } from 'ant-design-vue/es/table'
|
||||||
|
import { Modal, Table } from 'ant-design-vue'
|
||||||
|
|
||||||
|
export const deductedDetail = async (assessmentRecord: AssessmentRecordPagerVo) => {
|
||||||
|
const { data } = await api.get<DeductedDetailRes[]>('/m1/ar/deductedDetail', { assessmentRecordId: assessmentRecord.snowFlakeId })
|
||||||
|
const groupRowSpan: Record<string, { firstIndex: number; count: number }> = {}
|
||||||
|
const itemRowSpan: Record<string, { firstIndex: number; count: number }> = {}
|
||||||
|
|
||||||
|
data.forEach((item, index) => {
|
||||||
|
//如果第一次没有值
|
||||||
|
if (item.ckGroupId) {
|
||||||
|
if (!groupRowSpan[item.ckGroupId]) {
|
||||||
|
groupRowSpan[item.ckGroupId] = { count: 1, firstIndex: index }
|
||||||
|
} else {
|
||||||
|
groupRowSpan[item.ckGroupId].count++
|
||||||
|
data[index].groupRowSpan = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.ckItemId) {
|
||||||
|
if (!itemRowSpan[item.ckItemId]) {
|
||||||
|
itemRowSpan[item.ckItemId] = { count: 1, firstIndex: index }
|
||||||
|
} else {
|
||||||
|
itemRowSpan[item.ckItemId].count++
|
||||||
|
data[index].itemRowSpan = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Object.values(groupRowSpan).forEach(({ count, firstIndex }) => {
|
||||||
|
data[firstIndex].groupRowSpan = count
|
||||||
|
})
|
||||||
|
|
||||||
|
Object.values(itemRowSpan).forEach(({ count, firstIndex }) => {
|
||||||
|
data[firstIndex].itemRowSpan = count
|
||||||
|
})
|
||||||
|
|
||||||
|
const ckProjectDetailTableColumns: ColumnsType<DeductedDetailRes> = [
|
||||||
|
{
|
||||||
|
dataIndex: 'groupName',
|
||||||
|
title: '考核分组',
|
||||||
|
customCell: (_record) => {
|
||||||
|
return {
|
||||||
|
rowspan: _record.groupRowSpan,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
customRender: ({ record: _record }) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{_record.groupName}({_record.groupTotalScore})
|
||||||
|
</p>
|
||||||
|
<p>{_record.groupRemark}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'itemName',
|
||||||
|
title: '考核项',
|
||||||
|
customCell: (_record) => {
|
||||||
|
return {
|
||||||
|
rowspan: _record.itemRowSpan,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
customRender: ({ record: _record }) => {
|
||||||
|
if (!_record.ckItemId) {
|
||||||
|
return '/'
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{_record.itemName}({_record.itemType?.label})
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'standardName',
|
||||||
|
title: '标准',
|
||||||
|
customRender: ({ record: _record }) => {
|
||||||
|
if (!_record.ckStandardId) {
|
||||||
|
return '/'
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p style={{ color: _record.isSelected ? 'red' : '' }}>
|
||||||
|
{_record.standardName}扣{_record.deductionPoints}分
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
Modal.info({
|
||||||
|
title: `【${assessmentRecord.enterprisesUnitName}/${assessmentRecord.ckProjectName}】扣分详情`,
|
||||||
|
icon: ' ',
|
||||||
|
width: '80%',
|
||||||
|
centered: true,
|
||||||
|
content: () => (
|
||||||
|
<div style={{ height: '80vh', overflow: 'auto' }}>
|
||||||
|
<Table size='small' bordered pagination={false} class='margin-top-xs' columns={ckProjectDetailTableColumns} data-source={data}></Table>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TableProMax ref="tableRef" :request-api="reqApi" :columns="columns"> </TableProMax>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="tsx">
|
||||||
|
import TableProMax from '@/components/table/TableProMax.vue'
|
||||||
|
import api from '@/axios'
|
||||||
|
import { TableProMaxProps } from '@/types/components/table'
|
||||||
|
import { AssessmentRecordPagerQueryParams, AssessmentRecordPagerVo } from '@/types/views/assessmentRecord.ts'
|
||||||
|
import { ComponentExposed } from 'vue-component-type-helpers'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Modal } from 'ant-design-vue'
|
||||||
|
import { deductedDetail } from '@/views/query/assessmentIndex.tsx'
|
||||||
|
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
||||||
|
type TableProps = TableProMaxProps<AssessmentRecordPagerVo, AssessmentRecordPagerQueryParams>
|
||||||
|
const reqApi: TableProps['requestApi'] = (params) => api.post('/m1/ar/pager', params) //分页
|
||||||
|
const columns: TableProps['columns'] = [
|
||||||
|
{
|
||||||
|
dataIndex: 'enterprisesUnitName',
|
||||||
|
title: '单位名称',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
customRender: ({ text }) => text?.label,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'ckProjectName',
|
||||||
|
title: '考核项目',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'totalScore',
|
||||||
|
title: '总分',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'deductionPointsTotal',
|
||||||
|
title: '扣分',
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
if (!record.deductionPointsTotal) {
|
||||||
|
return <a-tag color='green'>0</a-tag>
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<a-tag class='pointer' color='red' onClick={() => deductedDetail(record)}>
|
||||||
|
{record.deductionPointsTotal}
|
||||||
|
</a-tag>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'result',
|
||||||
|
title: '得分',
|
||||||
|
customRender: ({ record }) => record.totalScore - record.deductionPointsTotal,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'policeUnitName',
|
||||||
|
title: '考核单位',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'createUserName',
|
||||||
|
title: '考核人',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
title: '考核时间',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'remark',
|
||||||
|
title: '考核备注',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'signature',
|
||||||
|
title: '签字',
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
return (
|
||||||
|
<a-button
|
||||||
|
onClick={() => {
|
||||||
|
Modal.info({
|
||||||
|
title: `${record.enterprisesUnitName}${record.ckProjectName} 签字结果`,
|
||||||
|
content: () => (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
审核人签字: <a-image src={record.assessmentUserSignature} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
被审核单位人员签字: <a-image src={record.byAssessmentEnterprisesUnitUserSignature} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</a-button>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,365 @@
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { TableProMaxProps, TableProMaxSlots } from '@/types/components/table'
|
||||||
|
import { EnterprisesUnitPagerQueryParams, securityUnitIdListPagerVo, securityUnitIdListParams, PoliceUnitPagerVo } from '@/types/views/unitManage/police/policeUnit.ts'
|
||||||
|
import { reactive, ref, h } from 'vue'
|
||||||
|
import { FormExpose } from 'ant-design-vue/es/form/Form'
|
||||||
|
import { ComponentExposed } from 'vue-component-type-helpers'
|
||||||
|
import { FormProMaxItemOptions } from '@/types/components/form'
|
||||||
|
import { dictSelectNodes } from '@/config/dict.ts'
|
||||||
|
import { Button, message, Modal, Space, Tag, Input } from 'ant-design-vue'
|
||||||
|
import api from '@/axios'
|
||||||
|
import TableProMax from '@/components/table/TableProMax.vue'
|
||||||
|
import { deleteDataModal } from '@/components/tsx/ModalPro.tsx'
|
||||||
|
import { PageParams } from '@/types/hooks/useTableProMax.ts'
|
||||||
|
import FormProMax from '@/components/form/FormProMax.vue'
|
||||||
|
import { debounce } from 'lodash-es'
|
||||||
|
import { SearchOutlined } from '@ant-design/icons-vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
import SingleImageFileUpload from '@/components/upload/SingleImageFileUpload.vue'
|
||||||
|
type _TableProps = TableProMaxProps<securityUnitIdListPagerVo, EnterprisesUnitPagerQueryParams>
|
||||||
|
|
||||||
|
const _formParams = reactive<securityUnitIdListParams>({
|
||||||
|
snowFlakeId: '', //
|
||||||
|
serviceProjectId: '', // 服务项目id
|
||||||
|
securityUnitId: '', // 保安单位id
|
||||||
|
name: '', //
|
||||||
|
photo: '',
|
||||||
|
telephone: '',
|
||||||
|
workPost: '',
|
||||||
|
sex: '',
|
||||||
|
nativePlace: '',
|
||||||
|
idCard: '',
|
||||||
|
dateOfBirth: '',
|
||||||
|
securityNumber: '',
|
||||||
|
noSecurityNumberDesc: '',
|
||||||
|
homeAddress: '',
|
||||||
|
remark: '',
|
||||||
|
})
|
||||||
|
const cardBlur = () => {
|
||||||
|
let value = _formParams.idCard
|
||||||
|
if (!value?.length || value.length < 18) {
|
||||||
|
_formParams.dateOfBirth = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const birthDate = value.substring(6, 14)
|
||||||
|
const year = birthDate.substring(0, 4)
|
||||||
|
const month = birthDate.substring(4, 6)
|
||||||
|
const day = birthDate.substring(6, 8)
|
||||||
|
var _data = new Date(parseInt(year), parseInt(month) - 1, parseInt(day))
|
||||||
|
_formParams.dateOfBirth = dayjs(_data).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
console.log('🚀 ~ cardBlur ~ _data:', _formParams.dateOfBirth)
|
||||||
|
}
|
||||||
|
const searchSecurityUnitId = debounce(async () => {
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
console.log('process.env.NODE_ENV === development')
|
||||||
|
const res = await axios.get(`https://www.hnjinglian.cn:5678/common/querySecurityNumberByIdCard?idCard=${_formParams.idCard}`)
|
||||||
|
if (res.data?.data?.hasOwnProperty('bayzh')) {
|
||||||
|
_formParams.securityNumber = res.data.data.bayzh
|
||||||
|
message.success(res.data.message)
|
||||||
|
} else {
|
||||||
|
message.error('未查询到保安证件号')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const res = await api.get<any>('/common/querySecurityNumberByIdCard', { idCard: _formParams.idCard })
|
||||||
|
console.log(res)
|
||||||
|
if (res.data?.hasOwnProperty('bayzh')) {
|
||||||
|
_formParams.securityNumber = res.data.bayzh
|
||||||
|
message.success(res.message)
|
||||||
|
} else {
|
||||||
|
message.error('未查询到保安证件号')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cardBlur()
|
||||||
|
}, 300)
|
||||||
|
const saveOrUpdateEnterprisesUnit = (callback: Function, params, type: string) => {
|
||||||
|
// console.log('🚀 ~ saveOrUpdateEnterprisesUnit ~ params:', params)
|
||||||
|
if (type === 'add') {
|
||||||
|
_formParams.serviceProjectId = params.snowFlakeId
|
||||||
|
_formParams.securityUnitId = params.securityUnitId
|
||||||
|
} else {
|
||||||
|
_formParams.snowFlakeId = params.snowFlakeId
|
||||||
|
_formParams.serviceProjectId = params.serviceProjectId
|
||||||
|
_formParams.securityUnitId = params.securityUnitId
|
||||||
|
_formParams.name = params.name
|
||||||
|
_formParams.photo = params?.photo
|
||||||
|
_formParams.telephone = params.telephone.originalValue
|
||||||
|
_formParams.workPost = params.workPost
|
||||||
|
_formParams.sex = params.sex.value
|
||||||
|
_formParams.nativePlace = params.nativePlace
|
||||||
|
_formParams.idCard = params.idCard.originalValue
|
||||||
|
_formParams.dateOfBirth = params.dateOfBirth
|
||||||
|
_formParams.securityNumber = params.securityNumber
|
||||||
|
_formParams.noSecurityNumberDesc = params?.noSecurityNumberDesc
|
||||||
|
_formParams.homeAddress = params.homeAddress
|
||||||
|
_formParams.remark = params.remark
|
||||||
|
}
|
||||||
|
|
||||||
|
const _formRef = ref<FormExpose>(null)
|
||||||
|
const uploadFileRef = ref(null)
|
||||||
|
const _formOptions = ref<FormProMaxItemOptions<securityUnitIdListParams>>({
|
||||||
|
photo: {
|
||||||
|
type: 'custom',
|
||||||
|
label: '头像',
|
||||||
|
customRender: () => <SingleImageFileUpload height={200} v-model:value={_formParams.photo} ref={uploadFileRef} />,
|
||||||
|
},
|
||||||
|
|
||||||
|
name: {
|
||||||
|
type: 'input',
|
||||||
|
label: '姓名',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
idCard: {
|
||||||
|
type: 'custom',
|
||||||
|
label: '身份证',
|
||||||
|
required: true,
|
||||||
|
customRender: () => (
|
||||||
|
<Space>
|
||||||
|
<Input allow-clear v-model:value={_formParams.idCard} placeholder={'请输入身份证号'} />
|
||||||
|
<Button type={'primary'} icon={h(SearchOutlined)} onClick={() => searchSecurityUnitId()}>
|
||||||
|
搜索保安证号
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
telephone: {
|
||||||
|
type: 'input',
|
||||||
|
label: '手机号',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
sex: {
|
||||||
|
type: 'radioGroup',
|
||||||
|
label: '性别',
|
||||||
|
required: true,
|
||||||
|
options: [...dictSelectNodes('Sex')],
|
||||||
|
},
|
||||||
|
securityNumber: {
|
||||||
|
type: 'input',
|
||||||
|
label: '保安证号',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
dateOfBirth: {
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '出生日期',
|
||||||
|
componentsProps: {
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
workPost: {
|
||||||
|
type: 'input',
|
||||||
|
label: '工作岗位',
|
||||||
|
},
|
||||||
|
nativePlace: {
|
||||||
|
type: 'input',
|
||||||
|
label: '籍贯',
|
||||||
|
},
|
||||||
|
homeAddress: {
|
||||||
|
type: 'input',
|
||||||
|
label: '家庭住址',
|
||||||
|
},
|
||||||
|
noSecurityNumberDesc: {
|
||||||
|
type: 'input',
|
||||||
|
label: '无证说明',
|
||||||
|
},
|
||||||
|
|
||||||
|
remark: {
|
||||||
|
type: 'inputTextArea',
|
||||||
|
label: '备注',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
Modal.confirm({
|
||||||
|
title: params.name ? `【${params.name}】 编辑保安信息` : '新增保安人员',
|
||||||
|
width: 600,
|
||||||
|
icon: ' ',
|
||||||
|
centered: true,
|
||||||
|
content: () => <FormProMax ref={_formRef} v-model:value={_formParams} formItemOptions={_formOptions.value} />,
|
||||||
|
onOk: async () => {
|
||||||
|
await _formRef.value?.validate()
|
||||||
|
const resp = await api.post('/m2/eu/add_upd_sec_user', {
|
||||||
|
..._formParams,
|
||||||
|
})
|
||||||
|
message.success(resp.message)
|
||||||
|
clearForm()
|
||||||
|
callback && callback()
|
||||||
|
},
|
||||||
|
onCancel: async () => {
|
||||||
|
clearForm()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const clearForm = () => {
|
||||||
|
_formParams.snowFlakeId = ''
|
||||||
|
_formParams.serviceProjectId = ''
|
||||||
|
_formParams.securityUnitId = ''
|
||||||
|
_formParams.name = ''
|
||||||
|
_formParams.photo = ''
|
||||||
|
_formParams.telephone = ''
|
||||||
|
_formParams.workPost = ''
|
||||||
|
_formParams.sex = ''
|
||||||
|
_formParams.nativePlace = ''
|
||||||
|
_formParams.idCard = ''
|
||||||
|
_formParams.dateOfBirth = ''
|
||||||
|
_formParams.securityNumber = ''
|
||||||
|
_formParams.noSecurityNumberDesc = ''
|
||||||
|
_formParams.homeAddress = ''
|
||||||
|
_formParams.remark = ''
|
||||||
|
}
|
||||||
|
export const showEnterprisesUnit = (record_) => {
|
||||||
|
// console.log('🚀 ~ showEnterprisesUnit ~ record_:', record_)
|
||||||
|
const _tableRef = ref<ComponentExposed<typeof TableProMax>>(null)
|
||||||
|
const _columns: _TableProps['columns'] = [
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
title: '姓名',
|
||||||
|
width: 100,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
dataIndex: 'idCard',
|
||||||
|
title: '身份证',
|
||||||
|
customRender: ({ text }) => {
|
||||||
|
return text.desensitizedValue
|
||||||
|
},
|
||||||
|
width: 160,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
dataIndex: 'sex',
|
||||||
|
title: '性别',
|
||||||
|
width: 60,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
return <Tag color={'success'}>{record.sex.label}</Tag>
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'dateOfBirth',
|
||||||
|
title: '出生日期',
|
||||||
|
width: 100,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'telephone',
|
||||||
|
title: '手机号',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
customRender: ({ text }) => text?.originalValue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'securityNumber',
|
||||||
|
title: '保安证号',
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'nativePlace',
|
||||||
|
title: '籍贯',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'workPost',
|
||||||
|
title: '工作岗位',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
dataIndex: 'homeAddress',
|
||||||
|
title: '家庭住址',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'remark',
|
||||||
|
title: '备注',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
title: '创建时间',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
dataIndex: 'opt',
|
||||||
|
title: '操作',
|
||||||
|
width: 200,
|
||||||
|
fixed: 'right',
|
||||||
|
customRender: ({ record }) => (
|
||||||
|
<Space>
|
||||||
|
<Button class='btn-warn' onClick={() => saveOrUpdateEnterprisesUnit(_tableRef.value?.requestGetTableData, record, 'edit')}>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
class='btn-danger'
|
||||||
|
onClick={() =>
|
||||||
|
deleteDataModal(record.name, async () => {
|
||||||
|
const resp = await api.delete('/m2/eu/del_security_user_id', {
|
||||||
|
securityUserId: record?.snowFlakeId,
|
||||||
|
})
|
||||||
|
message.success(resp.message)
|
||||||
|
await _tableRef.value?.requestGetTableData()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const x: number = _columns.reduce((a, b) => a + (b.width as number), 0)
|
||||||
|
const _reqApi: _TableProps['requestApi'] = (params) => {
|
||||||
|
// console.log(record_);
|
||||||
|
|
||||||
|
;(params as PageParams<EnterprisesUnitPagerQueryParams>).params.serviceProjectId = record_.snowFlakeId
|
||||||
|
return api.post('/m2/eu/sec_user_pager', params)
|
||||||
|
}
|
||||||
|
Modal.info({
|
||||||
|
title: `【${record_.name}】 管理保安人员`,
|
||||||
|
width: '80%',
|
||||||
|
centered: true,
|
||||||
|
maskClosable: true,
|
||||||
|
content: () => (
|
||||||
|
<TableProMax
|
||||||
|
scroll={{ x: x }}
|
||||||
|
ref={_tableRef}
|
||||||
|
size='small'
|
||||||
|
columns={_columns}
|
||||||
|
requestApi={_reqApi}
|
||||||
|
// searchFormOptions={{
|
||||||
|
// name: {
|
||||||
|
// type: 'input',
|
||||||
|
// label: '姓名',
|
||||||
|
// },
|
||||||
|
// securityNumber: {
|
||||||
|
// type: 'input',
|
||||||
|
// label: '保安证号',
|
||||||
|
// },
|
||||||
|
// telephone: {
|
||||||
|
// type: 'input',
|
||||||
|
// label: '手机号',
|
||||||
|
// },
|
||||||
|
// }}
|
||||||
|
v-slots={
|
||||||
|
{
|
||||||
|
tableHeader: (_) => {
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<Button class='btn-success' onClick={() => saveOrUpdateEnterprisesUnit(_tableRef.value?.requestGetTableData, record_, 'add')}>
|
||||||
|
新增
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
} as TableProMaxSlots<PoliceUnitPagerVo>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,72 +1,75 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 企事业单位 -->
|
<TableProMax
|
||||||
<TableProMax ref="tableRef" :request-api="reqApi" :columns="columns" :searchFormOptions="searchFormOptions"
|
style="width: 100%"
|
||||||
:scroll="{ x }">
|
:expandedRowRender="expandedRowRender"
|
||||||
<!-- <template #tableHeader>
|
:expand-column-width="50"
|
||||||
|
:defaultExpandAllRows="false"
|
||||||
|
ref="tableRef"
|
||||||
|
:request-api="reqApi"
|
||||||
|
:columns="columns"
|
||||||
|
:searchFormOptions="searchFormOptions"
|
||||||
|
:scroll="{ x: x }"
|
||||||
|
>
|
||||||
|
<template #tableHeader>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="addUserManagement">新增用户</a-button>
|
<a-button type="primary" @click="saveOrUpdateEnterprisesUnit">新增企事业单位</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template> -->
|
</template>
|
||||||
</TableProMax>
|
</TableProMax>
|
||||||
<a-modal v-model:open="visible" :title="title" @ok="submit" @cancel="closeModal">
|
<a-modal v-model:open="visible" :title="serviceTitle" @ok="submit" @cancel="closeModal">
|
||||||
<!-- <FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions" /> -->
|
<FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import {storeTreeData, loadTreeFromCache} from '@/utils/DB.ts'
|
import { deleteDataModal } from '@/components/tsx/ModalPro.tsx'
|
||||||
|
import { EnterprisesUnitSaveOrUpdateParams } from '@/types/views/unitManage/police/policeUnit.ts'
|
||||||
|
import MapContainer from '@/components/aMap/MapContainer.vue'
|
||||||
|
import { AutoComplete, Button, Input, message, Modal, Space } from 'ant-design-vue'
|
||||||
|
import { debounce } from 'lodash-es'
|
||||||
|
import FormProMax from '@/components/form/FormProMax.vue'
|
||||||
import api from '@/axios'
|
import api from '@/axios'
|
||||||
import {ref, reactive} from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import TableProMax from '@/components/table/TableProMax.vue'
|
import TableProMax from '@/components/table/TableProMax.vue'
|
||||||
import { TableProMaxProps } from '@/types/components/table/index.ts'
|
import { TableProMaxProps } from '@/types/components/table/index.ts'
|
||||||
import { ComponentExposed } from 'vue-component-type-helpers'
|
import { ComponentExposed } from 'vue-component-type-helpers'
|
||||||
import { dictSelectNodes } from '@/config/dict.ts'
|
import { dictSelectNodes } from '@/config/dict.ts'
|
||||||
import {publicUnitPagerQueryParams, FromItem} from '@/types/views/publicUnit.ts'
|
import { publicUnitPagerQueryParams } from '@/types/views/publicUnit.ts'
|
||||||
// import FormProMax from '@/components/form/FormProMax.vue'
|
|
||||||
import { FormProMaxItemOptions } from '@/types/components/form//index.ts'
|
import { FormProMaxItemOptions } from '@/types/components/form//index.ts'
|
||||||
import { FormExpose } from 'ant-design-vue/es/form/Form'
|
import { FormExpose } from 'ant-design-vue/es/form/Form'
|
||||||
import {message} from 'ant-design-vue'
|
import { serviceProjectSaveOrUpdateParams_ } from '@/types/views/serviceManagement'
|
||||||
|
import { showEnterprisesUnit } from './index.tsx'
|
||||||
const formRef = ref<FormExpose>(null)
|
type _FormType = EnterprisesUnitSaveOrUpdateParams & {
|
||||||
|
contactPersonInfoName?: string
|
||||||
|
contactPersonInfoTelephone?: string
|
||||||
|
}
|
||||||
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
|
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
|
||||||
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
|
||||||
const reqApi: TableProps['requestApi'] = (params) => api.post('/management/police/enterprisesUnitPager', params) //分页
|
|
||||||
|
|
||||||
|
const reqApi: TableProps['requestApi'] = (params) => api.post('/eu/pager', params) //分页
|
||||||
|
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null)
|
||||||
const columns: TableProps['columns'] = [
|
const columns: TableProps['columns'] = [
|
||||||
{
|
{
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
title: '单位名称',
|
title: '单位名称',
|
||||||
|
width: 200,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// dataIndex: 'code',
|
|
||||||
// title: '单位代码',
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
dataIndex: 'provinceName',
|
dataIndex: 'provinceName',
|
||||||
title: '行政区划',
|
title: '行政区划',
|
||||||
customRender: ({ record }) => {
|
customRender: ({ record }) => {
|
||||||
return `${record?.provinceName}/${record?.cityName}/${record?.districtsName}/${record?.streetName}`
|
return `${record?.provinceName}/${record?.cityName}/${record?.districtsName}/${record?.streetName}`
|
||||||
},
|
},
|
||||||
|
width: 300,
|
||||||
},
|
},
|
||||||
|
|
||||||
// {
|
|
||||||
// dataIndex: 'isEnable',
|
|
||||||
// title: '是否启用',
|
|
||||||
// customRender: ({ text }) => <a-tag color={text?.extData?.color}>{text?.label}</a-tag>,
|
|
||||||
// width: 150,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// dataIndex: 'checkStatus',
|
|
||||||
// title: '是否审核',
|
|
||||||
// customRender: ({ record }) => {
|
|
||||||
// return record.checkStatus?.extData?.color === 'success' ? <a-tag color='green'>{record?.checkStatus?.label}</a-tag> : <a-tag color='#f50'>{record?.checkStatus?.label}</a-tag>
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
dataIndex: 'address',
|
dataIndex: 'address',
|
||||||
title: '详细地址',
|
title: '详细地址',
|
||||||
|
width: 200,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -75,6 +78,7 @@ const columns: TableProps['columns'] = [
|
||||||
customRender: ({ record }) => {
|
customRender: ({ record }) => {
|
||||||
return record?.contactPersonInfo?.name
|
return record?.contactPersonInfo?.name
|
||||||
},
|
},
|
||||||
|
width: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'contactPersonInfo',
|
dataIndex: 'contactPersonInfo',
|
||||||
|
@ -82,116 +86,631 @@ const columns: TableProps['columns'] = [
|
||||||
customRender: ({ record }) => {
|
customRender: ({ record }) => {
|
||||||
return record?.contactPersonInfo?.telephone
|
return record?.contactPersonInfo?.telephone
|
||||||
},
|
},
|
||||||
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'remark',
|
dataIndex: 'remark',
|
||||||
title: '备注',
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 200,
|
||||||
|
dataIndex: 'opt',
|
||||||
|
title: '操作',
|
||||||
|
customRender: ({ record }) => (
|
||||||
|
<Space>
|
||||||
|
<Button
|
||||||
|
class='btn-warn'
|
||||||
|
onClick={() =>
|
||||||
|
saveOrUpdateEnterprisesUnit(
|
||||||
|
{
|
||||||
|
snowFlakeId: record.snowFlakeId,
|
||||||
|
policeUnitId: record.policeUnitId,
|
||||||
|
name: record.name,
|
||||||
|
type: record.type.value,
|
||||||
|
administrativeDivisionCodes: [record.province, record.city, record.districts, record.street].filter(Boolean),
|
||||||
|
address: record.address,
|
||||||
|
point: record.point,
|
||||||
|
contactPersonInfoName: record.contactPersonInfo?.name,
|
||||||
|
contactPersonInfoTelephone: record.contactPersonInfo?.telephone,
|
||||||
|
remark: record.remark,
|
||||||
|
},
|
||||||
|
tableRef.value?.requestGetTableData
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
class='btn-danger'
|
||||||
|
onClick={() =>
|
||||||
|
deleteDataModal(record.name, async () => {
|
||||||
|
// const resp = await api.delete('/enterprisesUnit/deleteById', {
|
||||||
|
const resp = await api.delete('/eu/del_id', {
|
||||||
|
enterprisesUnitId: record.snowFlakeId,
|
||||||
|
})
|
||||||
|
message.success(resp.message)
|
||||||
|
await tableRef.value?.requestGetTableData()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
|
// const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
|
||||||
const visible = ref(false)
|
const x: number = columns.reduce((a, b) => {
|
||||||
const title = ref('新增用户')
|
// console.log('x_____________________', a, b, b.width)
|
||||||
const addUserManagement = () => {
|
return a + (b.width as number)
|
||||||
visible.value = true
|
}, 0)
|
||||||
title.value = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const getTree = async () => {
|
const saveOrUpdateEnterprisesUnit = (params: _FormType, callback: Function) => {
|
||||||
// 先尝试从缓存中加载数据
|
const _formRef = ref<FormExpose>(null)
|
||||||
const cachedData = await loadTreeFromCache()
|
const _mapRef = ref<ComponentExposed<typeof MapContainer>>(null)
|
||||||
if (cachedData) {
|
const _formParams = ref<_FormType>({ ...params })
|
||||||
console.log('未发请求')
|
|
||||||
// 如果缓存存在,直接使用缓存数据
|
let city = ''
|
||||||
return cachedData
|
const initMarker = (map: AMap.Map) => {
|
||||||
|
//添加maker点 设置point
|
||||||
|
const maker = new AMap.Marker({
|
||||||
|
position: _formParams.value.point,
|
||||||
|
draggable: true,
|
||||||
|
})
|
||||||
|
maker.on('dragend', ({ lnglat }) => {
|
||||||
|
_formParams.value.point = lnglat
|
||||||
|
})
|
||||||
|
map.clearMap()
|
||||||
|
map.add(maker)
|
||||||
|
map.setFitView()
|
||||||
|
}
|
||||||
|
const autoAddress = ref<SelectNodeVo<string>[]>([])
|
||||||
|
|
||||||
|
const _formOptions = ref<FormProMaxItemOptions<_FormType>>({
|
||||||
|
name: {
|
||||||
|
type: 'custom',
|
||||||
|
label: '单位名称',
|
||||||
|
required: true,
|
||||||
|
customRender: () => {
|
||||||
|
return (
|
||||||
|
// AutoComplete 自动完成 组件
|
||||||
|
<AutoComplete
|
||||||
|
v-model:value={_formParams.value.name}
|
||||||
|
options={autoAddress.value}
|
||||||
|
onSelect={(_, options: SelectNodeVo<string>) => {
|
||||||
|
_formParams.value.point = options.extData?.location
|
||||||
|
_formParams.value.address = options.extData?.address
|
||||||
|
initMarker(_mapRef.value?.mapInstance)
|
||||||
|
}}
|
||||||
|
onSearch={debounce((val: string) => {
|
||||||
|
//@ts-ignore
|
||||||
|
const auto = new AMap.AutoComplete({
|
||||||
|
city: city,
|
||||||
|
// input: 'tipinput',
|
||||||
|
citylimit: true,
|
||||||
|
})
|
||||||
|
auto.search(val, (status, result) => {
|
||||||
|
if (status === 'complete') {
|
||||||
|
// 生成组件需要数据
|
||||||
|
autoAddress.value = result.tips?.map((e) => {
|
||||||
|
return {
|
||||||
|
value: e.name,
|
||||||
|
label: e.name,
|
||||||
|
extData: {
|
||||||
|
district: e.district,
|
||||||
|
address: e.address,
|
||||||
|
location: e.location,
|
||||||
|
},
|
||||||
|
} as SelectNodeVo<string>
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
console.log('发起了请求')
|
autoAddress.value = []
|
||||||
// 如果缓存不存在,发起 API 请求
|
|
||||||
const res = await api.get<any>('/common/administrativeDivisionTree')
|
|
||||||
await storeTreeData(res.data)
|
|
||||||
return res.data
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
const loadOptions = async () => {
|
}, 300)}
|
||||||
const treeData = await getTree()
|
v-slots={{
|
||||||
searchFormOptions.treeSelect.options = treeData
|
option: (item: SelectNodeVo<string>) => {
|
||||||
}
|
return (
|
||||||
loadOptions()
|
<div>
|
||||||
const searchFormOptions = reactive<TableProps['searchFormOptions']>({
|
<p>{item.label}</p>
|
||||||
name: {
|
<p style={{ color: '#9a9c9d' }}>
|
||||||
type: 'input',
|
{item.extData?.district} {item.extData?.address}
|
||||||
label: '名称',
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
},
|
},
|
||||||
treeSelect: {
|
}}
|
||||||
type: 'cascader',
|
>
|
||||||
|
<Input placeholder='请输入单位名称' />
|
||||||
|
</AutoComplete>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'select',
|
||||||
|
label: '单位类型',
|
||||||
|
required: true,
|
||||||
|
// @ts-ignore
|
||||||
|
options: dictSelectNodes('EnterprisesUnitType'),
|
||||||
|
},
|
||||||
|
administrativeDivisionCodes: {
|
||||||
|
type: 'administrativeDivisionTree',
|
||||||
label: '行政区划',
|
label: '行政区划',
|
||||||
|
required: true,
|
||||||
|
componentsProps: {
|
||||||
|
// @ts-ignore
|
||||||
|
displayRender: ({ labels }): string => {
|
||||||
|
city = labels[1]
|
||||||
|
return labels.join(' / ')
|
||||||
},
|
},
|
||||||
telephone: {
|
|
||||||
type: 'input',
|
|
||||||
label: '手机号',
|
|
||||||
},
|
},
|
||||||
// isEnable: {
|
},
|
||||||
// type: 'select',
|
address: {
|
||||||
// label: '是否启用',
|
type: 'inputTextArea',
|
||||||
// options: [
|
label: '详细地址',
|
||||||
// {
|
},
|
||||||
// value: null,
|
map: {
|
||||||
// label: '全部',
|
type: 'custom',
|
||||||
// },
|
label: '经纬度',
|
||||||
// ...dictSelectNodes('IsEnable'),
|
customRender: () => (
|
||||||
// ],
|
<MapContainer
|
||||||
// },
|
ref={_mapRef}
|
||||||
|
plugins={['AMap.AutoComplete', 'AMap.PlaceSearch']}
|
||||||
|
style={{ width: '100%', height: '300px', position: 'relative' }}
|
||||||
|
initCallback={(map) => {
|
||||||
|
const contextMenu = new AMap.ContextMenu()
|
||||||
|
contextMenu.addItem(
|
||||||
|
'标记',
|
||||||
|
() => {
|
||||||
|
const { lng, lat } = contextMenu.getPosition()
|
||||||
|
_formParams.value.point = [lng, lat]
|
||||||
|
initMarker(map)
|
||||||
|
},
|
||||||
|
0
|
||||||
|
)
|
||||||
|
map.on('rightclick', ({ lnglat }) => {
|
||||||
|
contextMenu.open(map, lnglat)
|
||||||
})
|
})
|
||||||
|
if (_formParams.value.point) {
|
||||||
const formParams = ref<{
|
initMarker(map)
|
||||||
snowFlakeId?: string
|
|
||||||
name: string
|
|
||||||
sex: number
|
|
||||||
telephone: string
|
|
||||||
isEnable: any
|
|
||||||
remark?: string
|
|
||||||
}>({
|
|
||||||
name: '',
|
|
||||||
sex: 0,
|
|
||||||
telephone: '',
|
|
||||||
isEnable: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
const submit = async () => {
|
|
||||||
// await formRef.value.validate()
|
|
||||||
}
|
}
|
||||||
const closeModal = () => {
|
}}
|
||||||
visible.value = false
|
></MapContainer>
|
||||||
}
|
),
|
||||||
const formItemOptions = ref<FormProMaxItemOptions<FromItem>>({
|
},
|
||||||
name: {
|
contactPersonInfoName: {
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: '姓名',
|
label: '联系人名称',
|
||||||
required: true,
|
|
||||||
},
|
},
|
||||||
sex: {
|
contactPersonInfoTelephone: {
|
||||||
type: 'radioGroup',
|
|
||||||
label: '性别',
|
|
||||||
options: dictSelectNodes('Sex'),
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
telephone: {
|
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: '手机号',
|
label: '联系人电话',
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
isEnable: {
|
|
||||||
type: 'radioGroup',
|
|
||||||
label: '启用状态',
|
|
||||||
options: dictSelectNodes('IsEnable'),
|
|
||||||
required: true,
|
|
||||||
},
|
},
|
||||||
remark: {
|
remark: {
|
||||||
type: 'inputTextArea',
|
type: 'inputTextArea',
|
||||||
label: '备注',
|
label: '备注',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Modal.confirm({
|
||||||
|
title: params.snowFlakeId ? `【${params.name}】 信息编辑` : '新增企事业单位',
|
||||||
|
width: 600,
|
||||||
|
icon: ' ',
|
||||||
|
centered: true,
|
||||||
|
content: () => <FormProMax ref={_formRef} v-model:value={_formParams.value} formItemOptions={_formOptions.value} />,
|
||||||
|
onOk: debounce(async () => {
|
||||||
|
await _formRef.value?.validate()
|
||||||
|
|
||||||
|
const resp = await api.post('/eu/add_upd', {
|
||||||
|
..._formParams.value,
|
||||||
|
contactPersonInfo: {
|
||||||
|
name: _formParams.value.contactPersonInfoName,
|
||||||
|
telephone: _formParams.value.contactPersonInfoTelephone,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
message.success(resp.message)
|
||||||
|
await tableRef.value?.requestGetTableData()
|
||||||
|
|
||||||
|
callback && callback()
|
||||||
|
}, 300),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchFormOptions = reactive<TableProps['searchFormOptions']>({
|
||||||
|
name: {
|
||||||
|
type: 'input',
|
||||||
|
label: '名称',
|
||||||
|
},
|
||||||
|
treeSelect: {
|
||||||
|
// type: 'cascader',
|
||||||
|
type: 'administrativeDivisionTree',
|
||||||
|
label: '行政区划',
|
||||||
|
},
|
||||||
|
telephone: {
|
||||||
|
type: 'input',
|
||||||
|
label: '手机号',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
type _TableProps = TableProMaxProps<any>
|
||||||
|
const isRecruitSecurityHidden = ref<boolean>(false)
|
||||||
|
const visible = ref(false)
|
||||||
|
const serviceTitle = ref('新增服务项目')
|
||||||
|
const idNumberDisabled = ref<boolean>(true)
|
||||||
|
const formRef = ref<FormExpose>(null)
|
||||||
|
const enterprisesUnitId = ref('')
|
||||||
|
const netType = computed(() => {
|
||||||
|
//@ts-ignore
|
||||||
|
return formParams.value.type === 'security' ? dictSelectNodes('ServiceProjectTwoType') : dictSelectNodes('UserType' as any)
|
||||||
|
})
|
||||||
|
const formParams = ref<{
|
||||||
|
snowFlakeId?: string
|
||||||
|
enterprisesUnitId: string
|
||||||
|
securityUnitId: string
|
||||||
|
administrativeDivisionCodes?: null
|
||||||
|
projectManagerMiniProgramUserId?: string
|
||||||
|
projectManagerMiniProgramUserName?: string
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
twoType?: number
|
||||||
|
outsourceName?: string
|
||||||
|
isFiling?: number
|
||||||
|
idNumber?: string
|
||||||
|
serviceArea?: number
|
||||||
|
buildingTotal?: number
|
||||||
|
houseTotal?: number
|
||||||
|
staffTotal?: number
|
||||||
|
securityUserTotal?: number
|
||||||
|
remark?: string
|
||||||
|
}>({
|
||||||
|
name: '',
|
||||||
|
enterprisesUnitId: null,
|
||||||
|
type: 'security',
|
||||||
|
securityUnitId: null,
|
||||||
|
})
|
||||||
|
const securityUnitIdList = ref<any>([])
|
||||||
|
const formItemOptions = ref<FormProMaxItemOptions<serviceProjectSaveOrUpdateParams_>>({
|
||||||
|
name: {
|
||||||
|
type: 'input',
|
||||||
|
label: '服务项目名称',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
securityUnitId: {
|
||||||
|
type: 'select',
|
||||||
|
label: '保安单位',
|
||||||
|
required: true,
|
||||||
|
options: securityUnitIdList,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'radioGroup',
|
||||||
|
label: '服务类型',
|
||||||
|
//@ts-ignore
|
||||||
|
options: dictSelectNodes('ServiceProjectType'),
|
||||||
|
required: true,
|
||||||
|
componentsProps: {
|
||||||
|
onChange: (e) => {
|
||||||
|
if (e.target?.value === 'security') {
|
||||||
|
isRecruitSecurityHidden.value = false
|
||||||
|
formParams.value.twoType = null
|
||||||
|
} else {
|
||||||
|
formParams.value.twoType = null
|
||||||
|
isRecruitSecurityHidden.value = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
twoType: {
|
||||||
|
required: true,
|
||||||
|
type: 'radioGroup',
|
||||||
|
label: '二级类型',
|
||||||
|
options: netType,
|
||||||
|
componentsProps: {
|
||||||
|
onChange: (e) => {
|
||||||
|
if (e.target.value !== 'outsource') {
|
||||||
|
idNumberDisabled.value = true
|
||||||
|
formParams.value.outsourceName = ''
|
||||||
|
} else {
|
||||||
|
idNumberDisabled.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
outsourceName: {
|
||||||
|
type: 'input',
|
||||||
|
label: '外包公司名称',
|
||||||
|
hidden: idNumberDisabled as any,
|
||||||
|
},
|
||||||
|
isFiling: {
|
||||||
|
required: true,
|
||||||
|
type: 'radioGroup',
|
||||||
|
label: '是否备案',
|
||||||
|
options: dictSelectNodes('IsOrNot'),
|
||||||
|
},
|
||||||
|
idNumber: {
|
||||||
|
type: 'input',
|
||||||
|
label: '保安服务许可证',
|
||||||
|
},
|
||||||
|
serviceArea: {
|
||||||
|
type: 'inputNumber',
|
||||||
|
label: '服务区域面积',
|
||||||
|
},
|
||||||
|
buildingTotal: {
|
||||||
|
type: 'inputNumber',
|
||||||
|
label: '楼栋数量',
|
||||||
|
componentsProps: {
|
||||||
|
formatter: (value: any) => {
|
||||||
|
return Math.round(value) ? Math.round(value) : ('' as any)
|
||||||
|
},
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
houseTotal: {
|
||||||
|
type: 'inputNumber',
|
||||||
|
label: '户数',
|
||||||
|
componentsProps: {
|
||||||
|
formatter: (value: any) => {
|
||||||
|
return Math.round(value) ? Math.round(value) : ('' as any)
|
||||||
|
},
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
staffTotal: {
|
||||||
|
type: 'inputNumber',
|
||||||
|
label: '工作人员数量',
|
||||||
|
componentsProps: {
|
||||||
|
formatter: (value: any) => {
|
||||||
|
return Math.round(value) ? Math.round(value) : ('' as any)
|
||||||
|
},
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
securityUserTotal: {
|
||||||
|
type: 'inputNumber',
|
||||||
|
label: '保安人员数量',
|
||||||
|
componentsProps: {
|
||||||
|
formatter: (value: any) => {
|
||||||
|
return Math.round(value) ? Math.round(value) : ('' as any)
|
||||||
|
},
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
remark: {
|
||||||
|
type: 'inputTextArea',
|
||||||
|
label: '备注',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const _tableRef = ref(null)
|
||||||
|
|
||||||
|
const deleteAccount = async (snowFlakeId) => {
|
||||||
|
const resp = await api.delete('/m2/eu/deleteSpById', {
|
||||||
|
serviceProjectId: snowFlakeId,
|
||||||
|
})
|
||||||
|
message.success(resp.message)
|
||||||
|
await _tableRef.value?.requestGetTableData()
|
||||||
|
}
|
||||||
|
const expandedRowRender: TableProMaxProps['expandedRowRender'] = ({ record }) => {
|
||||||
|
const _columns: _TableProps['columns'] = [
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
title: '服务项目名称',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '服务类型',
|
||||||
|
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'twoType',
|
||||||
|
title: '二级类型',
|
||||||
|
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'outsourceName',
|
||||||
|
title: '外包公司名称',
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
if (record.twoType.value === 'outsource') {
|
||||||
|
return record.outsourceName
|
||||||
|
}
|
||||||
|
},
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'isFiling',
|
||||||
|
title: '是否备案',
|
||||||
|
customRender: ({ text }) => {
|
||||||
|
if (text?.label === '是') {
|
||||||
|
return <a-tag color={'success'}>{text?.label}</a-tag>
|
||||||
|
} else {
|
||||||
|
return <a-tag color={'error'}>{text?.label}</a-tag>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'idNumber',
|
||||||
|
title: '保安服务许可证',
|
||||||
|
width: 200,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
dataIndex: 'serviceArea',
|
||||||
|
title: '服务区域面积',
|
||||||
|
width: 60,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'buildingTotal',
|
||||||
|
title: '楼栋数量',
|
||||||
|
width: 60,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
dataIndex: 'houseTotal',
|
||||||
|
title: '户数',
|
||||||
|
width: 60,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'staffTotal',
|
||||||
|
title: '工作人员数量',
|
||||||
|
width: 60,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'securityUserTotal',
|
||||||
|
title: '保安人员数量',
|
||||||
|
width: 60,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'remark',
|
||||||
|
title: '备注',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'createUserInfo',
|
||||||
|
title: '创建人',
|
||||||
|
width: 200,
|
||||||
|
ellipsis: true,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>创建人:{record.createUserInfo.name} </p>
|
||||||
|
|
||||||
|
<p>创建人单位:{record.createUserInfo.unitName} </p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
title: '创建时间',
|
||||||
|
width: 120,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'opt',
|
||||||
|
title: '操作',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 300,
|
||||||
|
customRender({ record }) {
|
||||||
|
return (
|
||||||
|
<a-space>
|
||||||
|
<a-button class='btn-success' onClick={() => showEnterprisesUnit(record)}>
|
||||||
|
保安人员
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
class='btn-warn'
|
||||||
|
onClick={async () => {
|
||||||
|
visible.value = true
|
||||||
|
serviceTitle.value = '编辑服务项目'
|
||||||
|
idNumberDisabled.value = record.twoType.value !== 'outsource'
|
||||||
|
formParams.value.securityUnitId = record.securityUnitId //企事业单位id
|
||||||
|
formParams.value.enterprisesUnitId = record.enterprisesUnitId //企事业单位id
|
||||||
|
formParams.value.snowFlakeId = record.snowFlakeId //id
|
||||||
|
formParams.value.projectManagerMiniProgramUserId = record.projectManagerMiniProgramUserId //项目经理小程序用户id
|
||||||
|
formParams.value.name = record.name
|
||||||
|
formParams.value.type = record.type.value //服务类型
|
||||||
|
formParams.value.twoType = record.twoType.value //二级类型
|
||||||
|
formParams.value.outsourceName = record.outsourceName //外包公司名称
|
||||||
|
formParams.value.isFiling = record.isFiling.value //是否备案
|
||||||
|
formParams.value.remark = record.remark //备注
|
||||||
|
formParams.value.idNumber = record.idNumber //证件号(保安服务许可证/备案证
|
||||||
|
formParams.value.serviceArea = record.serviceArea //服务区域面积
|
||||||
|
formParams.value.buildingTotal = record.buildingTotal //楼栋数量
|
||||||
|
formParams.value.houseTotal = record.houseTotal //户数
|
||||||
|
formParams.value.staffTotal = record.staffTotal //工作人员数量
|
||||||
|
formParams.value.securityUserTotal = record.securityUserTotal //保安人员数量
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</a-button>
|
||||||
|
<a-popconfirm title='确认删除账号吗?' onConfirm={() => deleteAccount(record.snowFlakeId)}>
|
||||||
|
<a-button danger>删除</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const x2: number = _columns.reduce((a, b) => a + (b.width as number), 0)
|
||||||
|
const _reqApi: _TableProps['requestApi'] = async () => {
|
||||||
|
// @ts-ignore
|
||||||
|
return await api.get('/m2/eu/listSp', { enterprisesUnitId: record?.snowFlakeId })
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TableProMax
|
||||||
|
scroll={{ x: x2 }}
|
||||||
|
ref={_tableRef}
|
||||||
|
size='small'
|
||||||
|
columns={_columns}
|
||||||
|
requestApi={_reqApi}
|
||||||
|
isPagination={false}
|
||||||
|
v-slots={{
|
||||||
|
tableHeader: () => {
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<Button type={'primary'} onClick={() => addService(record)}>
|
||||||
|
新增服务项目
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeModal = async () => {
|
||||||
|
visible.value = false
|
||||||
|
formParams.value = {
|
||||||
|
securityUnitId: '',
|
||||||
|
enterprisesUnitId: '',
|
||||||
|
administrativeDivisionCodes: '',
|
||||||
|
name: '',
|
||||||
|
type: 'security',
|
||||||
|
idNumber: '',
|
||||||
|
serviceArea: null,
|
||||||
|
buildingTotal: null,
|
||||||
|
houseTotal: null,
|
||||||
|
staffTotal: null,
|
||||||
|
securityUserTotal: null,
|
||||||
|
remark: '',
|
||||||
|
}
|
||||||
|
formRef.value.resetFields()
|
||||||
|
enterprisesUnitId.value = ''
|
||||||
|
serviceTitle.value = '新增服务项目'
|
||||||
|
idNumberDisabled.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
await formRef.value.validate()
|
||||||
|
const serviceProjectSaveOrUpdateParams = { ...formParams.value }
|
||||||
|
const resp = await api.post('/m2/eu/add_upd_sp', serviceProjectSaveOrUpdateParams)
|
||||||
|
message.success(resp.message)
|
||||||
|
await _tableRef.value.requestGetTableData()
|
||||||
|
await closeModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const res = await api.get('/management/listSecurityUnit')
|
||||||
|
securityUnitIdList.value = res.data
|
||||||
|
})
|
||||||
|
const addService = function (record) {
|
||||||
|
formParams.value.enterprisesUnitId = record.snowFlakeId //企事业单位Id
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
<div style="height: 100%">
|
<div style="height: 100%">
|
||||||
<a-form-item v-if="options.length > 0" label="行政区划">
|
<a-form-item v-if="options.length > 0" label="行政区划">
|
||||||
<a-cascader
|
<a-cascader
|
||||||
|
change-on-select
|
||||||
|
:load-data="loadData"
|
||||||
:field-names="{ label: 'label', value: 'value', children: 'children' }"
|
:field-names="{ label: 'label', value: 'value', children: 'children' }"
|
||||||
@change="cascaderChange"
|
@change="cascaderChange"
|
||||||
style="width: 300px"
|
style="width: 300px"
|
||||||
|
@ -77,7 +79,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { storeTreeData, loadTreeFromCache } from '@/utils/DB.ts'
|
// import { storeTreeData, loadTreeFromCache } from '@/utils/DB.ts'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
||||||
|
@ -89,35 +91,53 @@ defineComponent({
|
||||||
name: 'Register',
|
name: 'Register',
|
||||||
})
|
})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getTree()
|
getTree(0)
|
||||||
})
|
})
|
||||||
|
import type { CascaderProps } from 'ant-design-vue'
|
||||||
|
const loadData: CascaderProps['loadData'] = async (selectedOptions) => {
|
||||||
|
const targetOption = selectedOptions[selectedOptions.length - 1]
|
||||||
|
targetOption.loading = true
|
||||||
|
const res = await api.get<any>('/common/administrativeDivisionByParentCode', { parentCode: targetOption.value })
|
||||||
|
for (let index = 0; index < res.data.length; index++) {
|
||||||
|
delete res.data[index].children
|
||||||
|
}
|
||||||
|
targetOption.children = [...res.data]
|
||||||
|
options.value = [...options.value]
|
||||||
|
targetOption.loading = false
|
||||||
|
}
|
||||||
const labelCol = { style: { width: '120px' } }
|
const labelCol = { style: { width: '120px' } }
|
||||||
const wrapperCol = { span: 14 }
|
const wrapperCol = { span: 14 }
|
||||||
const filter: ShowSearchType['filter'] = (inputValue, path) => {
|
const filter: ShowSearchType['filter'] = (inputValue, path) => {
|
||||||
return path.some((option) => option.title.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
|
return path.some((option) => option.title.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
|
||||||
}
|
}
|
||||||
const value = ref<string[]>([])
|
const value = ref<string[]>([])
|
||||||
const options = ref<any[]>([])
|
const options = ref<CascaderProps['options']>([])
|
||||||
|
|
||||||
const cascaderChange = (value: any): void => {
|
const cascaderChange = (value: any): void => {
|
||||||
formState.administrativeDivisionCodes = [...value]
|
formState.administrativeDivisionCodes = [...value]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取树形结构数据并存储在 IndexedDB 中的主函数
|
// 获取树形结构数据并存储在 IndexedDB 中的主函数
|
||||||
const getTree = async () => {
|
const getTree = async (parentCode: string | number) => {
|
||||||
// 先尝试从缓存中加载数据
|
const res = await api.get<any>('/common/administrativeDivisionByParentCode', { parentCode })
|
||||||
const cachedData = await loadTreeFromCache()
|
for (let index = 0; index < res.data.length; index++) {
|
||||||
if (cachedData) {
|
delete res.data[index].children
|
||||||
console.log('未发请求')
|
|
||||||
// 如果缓存存在,直接使用缓存数据
|
|
||||||
options.value = cachedData
|
|
||||||
// console.log('Loaded from cache:', cachedData)
|
|
||||||
} else {
|
|
||||||
console.log('发起了请求')
|
|
||||||
// 如果缓存不存在,发起 API 请求
|
|
||||||
const res = await api.get<any>('/common/administrativeDivisionTree')
|
|
||||||
options.value = res.data
|
|
||||||
await storeTreeData(res.data)
|
|
||||||
}
|
}
|
||||||
|
options.value = res.data
|
||||||
|
// // 先尝试从缓存中加载数据
|
||||||
|
// const cachedData = await loadTreeFromCache()
|
||||||
|
// if (cachedData) {
|
||||||
|
// console.log('未发请求')
|
||||||
|
// // 如果缓存存在,直接使用缓存数据
|
||||||
|
// options.value = cachedData
|
||||||
|
// // console.log('Loaded from cache:', cachedData)
|
||||||
|
// } else {
|
||||||
|
// console.log('发起了请求')
|
||||||
|
// // 如果缓存不存在,发起 API 请求
|
||||||
|
// const res = await api.get<any>('/common/administrativeDivisionTree', { level: 0 })
|
||||||
|
// options.value = res.data
|
||||||
|
// await storeTreeData(res.data)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
import type { Rule } from 'ant-design-vue/es/form'
|
import type { Rule } from 'ant-design-vue/es/form'
|
||||||
import type { FormInstance } from 'ant-design-vue'
|
import type { FormInstance } from 'ant-design-vue'
|
||||||
|
@ -245,6 +265,7 @@ const getCheckStatus = async () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
import { useUserStore } from '@/stores/modules/userStore.ts'
|
import { useUserStore } from '@/stores/modules/userStore.ts'
|
||||||
|
import { log } from 'console'
|
||||||
const showConfirm = (columnsDate: dataStatus) => {
|
const showConfirm = (columnsDate: dataStatus) => {
|
||||||
if (columnsDate.checkStatus.value === 0) {
|
if (columnsDate.checkStatus.value === 0) {
|
||||||
Modal.success({
|
Modal.success({
|
||||||
|
|
|
@ -2,13 +2,7 @@
|
||||||
<!-- 后台用户 -->
|
<!-- 后台用户 -->
|
||||||
<!-- template 内部必须有一个根节点 div,否则<Transition>将会失效,所以这个<a-modal></a-modal> 组件必须放在 根节点 div 里面 -->
|
<!-- template 内部必须有一个根节点 div,否则<Transition>将会失效,所以这个<a-modal></a-modal> 组件必须放在 根节点 div 里面 -->
|
||||||
<div>
|
<div>
|
||||||
<TableProMax
|
<TableProMax ref="tableRef" :request-api="reqApi" :columns="columns" :searchFormOptions="searchFormOptions" :scroll="{ x }">
|
||||||
ref="tableRef"
|
|
||||||
:request-api="reqApi"
|
|
||||||
:columns="columns"
|
|
||||||
:searchFormOptions="searchFormOptions"
|
|
||||||
:scroll="{x}"
|
|
||||||
>
|
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="addUserManagement">新增用户</a-button>
|
<a-button type="primary" @click="addUserManagement">新增用户</a-button>
|
||||||
|
@ -23,30 +17,31 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import TableProMax from "@/components/table/TableProMax.vue";
|
import TableProMax from '@/components/table/TableProMax.vue'
|
||||||
import {TableProMaxProps} from "@/types/components/table";
|
import { TableProMaxProps } from '@/types/components/table'
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import { dictSelectNodes } from '@/config/dict.ts'
|
import { dictSelectNodes } from '@/config/dict.ts'
|
||||||
// const enumsSex = ref<any[]>(dictSelectNodes('Sex'))
|
// const enumsSex = ref<any[]>(dictSelectNodes('Sex'))
|
||||||
// const enumsIsEnable = ref<any[]>(dictSelectNodes('IsEnable'))
|
// const enumsIsEnable = ref<any[]>(dictSelectNodes('IsEnable'))
|
||||||
import api from '@/axios/index.ts'
|
import api from '@/axios/index.ts'
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import FormProMax from "@/components/form/FormProMax.vue";
|
import FormProMax from '@/components/form/FormProMax.vue'
|
||||||
import {FormProMaxItemOptions} from "@/types/components/form";
|
import { FormProMaxItemOptions } from '@/types/components/form'
|
||||||
import {FormExpose} from "ant-design-vue/es/form/Form";
|
import { FormExpose } from 'ant-design-vue/es/form/Form'
|
||||||
import {publicUnitPagerQueryParams, FromItem} from "@/types/views/publicUnit.ts";
|
import { publicUnitPagerQueryParams, FromItem } from '@/types/views/publicUnit.ts'
|
||||||
|
import { ComponentExposed } from 'vue-component-type-helpers'
|
||||||
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
||||||
const formRef = ref<FormExpose>(null)
|
const formRef = ref<FormExpose>(null)
|
||||||
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
|
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
|
||||||
const reqApi: TableProps['requestApi'] = (params) => api.post('/management/police/user/pager', params) //分页
|
// const reqApi: TableProps['requestApi'] = (params) => api.post('/management/police/user/pager', params) //分页
|
||||||
const formParams = ref<{
|
const reqApi: TableProps['requestApi'] = (params) => api.post('/m2/user/pager', params) //分页
|
||||||
snowFlakeId?: string,
|
|
||||||
name: string,
|
|
||||||
sex: number,
|
|
||||||
telephone: string,
|
|
||||||
isEnable: any,
|
|
||||||
|
|
||||||
|
const formParams = ref<{
|
||||||
|
snowFlakeId?: string
|
||||||
|
name: string
|
||||||
|
sex: number
|
||||||
|
telephone: string
|
||||||
|
isEnable: any
|
||||||
}>({
|
}>({
|
||||||
name: '',
|
name: '',
|
||||||
sex: 0,
|
sex: 0,
|
||||||
|
@ -58,9 +53,7 @@ const formItemOptions = ref<FormProMaxItemOptions<FromItem>>({
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: '姓名',
|
label: '姓名',
|
||||||
required: true,
|
required: true,
|
||||||
rules: [
|
rules: [{ required: true, message: '请输入姓名' }],
|
||||||
{required: true, message: '请输入姓名'}
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
sex: {
|
sex: {
|
||||||
type: 'radioGroup',
|
type: 'radioGroup',
|
||||||
|
@ -78,11 +71,11 @@ const formItemOptions = ref<FormProMaxItemOptions<FromItem>>({
|
||||||
validator: (rule, value) => {
|
validator: (rule, value) => {
|
||||||
const phoneRegex = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
|
const phoneRegex = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return Promise.reject('手机号不能为空');
|
return Promise.reject('手机号不能为空')
|
||||||
} else if (!phoneRegex.test(value)) {
|
} else if (!phoneRegex.test(value)) {
|
||||||
return Promise.reject('手机号格式不正确');
|
return Promise.reject('手机号格式不正确')
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve();
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
|
@ -101,25 +94,25 @@ const columns: TableProps['columns'] = [
|
||||||
dataIndex: 'account',
|
dataIndex: 'account',
|
||||||
title: '账号',
|
title: '账号',
|
||||||
width: 100,
|
width: 100,
|
||||||
ellipsis: true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
title: '名称',
|
title: '名称',
|
||||||
width: 200,
|
width: 200,
|
||||||
ellipsis: true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'sex',
|
dataIndex: 'sex',
|
||||||
title: '性别',
|
title: '性别',
|
||||||
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
|
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
|
||||||
width: 150
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'telephone',
|
dataIndex: 'telephone',
|
||||||
title: '手机号码',
|
title: '手机号码',
|
||||||
width: 150,
|
width: 150,
|
||||||
ellipsis: true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
|
@ -132,65 +125,71 @@ const columns: TableProps['columns'] = [
|
||||||
dataIndex: 'isEnable',
|
dataIndex: 'isEnable',
|
||||||
title: '是否启用',
|
title: '是否启用',
|
||||||
customRender: ({ text }) => <a-tag color={text?.extData?.color}>{text?.label}</a-tag>,
|
customRender: ({ text }) => <a-tag color={text?.extData?.color}>{text?.label}</a-tag>,
|
||||||
width: 150
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'opt',
|
dataIndex: 'opt',
|
||||||
title: '操作',
|
title: '操作',
|
||||||
fixed: "right",
|
fixed: 'right',
|
||||||
customRender({ record }) {
|
customRender({ record }) {
|
||||||
return (
|
return record.isAdmin.value === 1 ? (
|
||||||
record.isAdmin.value === 1 ?
|
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-popconfirm
|
<a-popconfirm
|
||||||
style="width:100%"
|
style='width:100%'
|
||||||
title="确认删除账号吗?"
|
title='确认删除账号吗?'
|
||||||
onConfirm={async () => {
|
onConfirm={async () => {
|
||||||
const resp = await api.delete('/management/police/user/deleteById', {
|
{
|
||||||
|
/* const resp = await api.delete('/management/police/user/deleteById', { */
|
||||||
|
}
|
||||||
|
const resp = await api.delete('/m2/user/del_id', {
|
||||||
managementPoliceUnitUserId: record.snowFlakeId,
|
managementPoliceUnitUserId: record.snowFlakeId,
|
||||||
})
|
})
|
||||||
message.success(resp.message)
|
message.success(resp.message)
|
||||||
await tableRef.value?.requestGetTableData()
|
await tableRef.value?.requestGetTableData()
|
||||||
}}>
|
}}
|
||||||
<a-button type="primary" danger>删除</a-button>
|
>
|
||||||
|
<a-button type='primary' danger>
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
<a-button type="primary" onClick={async () => {
|
<a-button
|
||||||
|
type='primary'
|
||||||
|
onClick={async () => {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
title.value = "编辑用户"
|
title.value = '编辑用户'
|
||||||
formParams.value.snowFlakeId = record.snowFlakeId
|
formParams.value.snowFlakeId = record.snowFlakeId
|
||||||
formParams.value.name = record.name,
|
;(formParams.value.name = record.name), (formParams.value.sex = record.sex.value), (formParams.value.telephone = record.telephone), (formParams.value.isEnable = record.isEnable?.value)
|
||||||
formParams.value.sex = record.sex.value,
|
}}
|
||||||
formParams.value.telephone = record.telephone,
|
>
|
||||||
formParams.value.isEnable = record.isEnable?.value
|
|
||||||
|
|
||||||
}}>
|
|
||||||
编辑
|
编辑
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
:
|
) : (
|
||||||
<div>超级管理员不能编辑</div>
|
<div>超级管理员不能编辑</div>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
|
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
|
||||||
const searchFormOptions: TableProps["searchFormOptions"] = {
|
const searchFormOptions: TableProps['searchFormOptions'] = {
|
||||||
name: {
|
name: {
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: '名称'
|
label: '名称',
|
||||||
}, sex: {
|
},
|
||||||
|
sex: {
|
||||||
type: 'select',
|
type: 'select',
|
||||||
label: '性别',
|
label: '性别',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: null,
|
value: null,
|
||||||
label: '全部'
|
label: '全部',
|
||||||
}, ...dictSelectNodes('Sex')
|
},
|
||||||
]
|
...dictSelectNodes('Sex'),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
telephone: {
|
telephone: {
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: '手机号'
|
label: '手机号',
|
||||||
},
|
},
|
||||||
isEnable: {
|
isEnable: {
|
||||||
type: 'select',
|
type: 'select',
|
||||||
|
@ -198,10 +197,11 @@ const searchFormOptions: TableProps["searchFormOptions"] = {
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: null,
|
value: null,
|
||||||
label: '全部'
|
label: '全部',
|
||||||
}, ...dictSelectNodes('IsEnable')
|
},
|
||||||
]
|
...dictSelectNodes('IsEnable'),
|
||||||
}
|
],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const title = ref('新增用户')
|
const title = ref('新增用户')
|
||||||
|
@ -222,13 +222,13 @@ const submit = async () => {
|
||||||
sex: formParams.value.sex,
|
sex: formParams.value.sex,
|
||||||
telephone: formParams.value.telephone,
|
telephone: formParams.value.telephone,
|
||||||
isEnable: formParams.value.isEnable,
|
isEnable: formParams.value.isEnable,
|
||||||
|
|
||||||
}
|
}
|
||||||
const resp = await api.post('/management/police/user/saveOrUpdate', managementSecurityUnitUserSaveOrUpdateParams)
|
// const resp = await api.post('/management/police/user/saveOrUpdate', managementSecurityUnitUserSaveOrUpdateParams)
|
||||||
|
const resp = await api.post('/m2/user/add_upd', managementSecurityUnitUserSaveOrUpdateParams)
|
||||||
|
|
||||||
message.success(resp.message)
|
message.success(resp.message)
|
||||||
tableRef.value?.requestGetTableData()
|
tableRef.value?.requestGetTableData()
|
||||||
closeModal()
|
closeModal()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
|
@ -236,7 +236,7 @@ const closeModal = () => {
|
||||||
name: '',
|
name: '',
|
||||||
sex: 0,
|
sex: 0,
|
||||||
telephone: '',
|
telephone: '',
|
||||||
isEnable: 0
|
isEnable: 0,
|
||||||
}
|
}
|
||||||
visible.value = false
|
visible.value = false
|
||||||
title.value = '新增用户'
|
title.value = '新增用户'
|
||||||
|
|
|
@ -1,8 +1,198 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 三色预警 -->
|
<TableProMax ref="tableRef" :request-api="reqApi" :columns="columns">
|
||||||
三色预警
|
</TableProMax>
|
||||||
|
<div>
|
||||||
|
<a-modal v-model:open="open" :title="title" @ok="open = false" width="80%">
|
||||||
|
<a-table :columns="TableColumns" :data-source="TableData" bordered >
|
||||||
|
<template #bodyCell="{ column, text }">
|
||||||
|
<template v-if="column.dataIndex === 'name'">
|
||||||
|
<div>{{text}}{{column}}</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="tsx">
|
||||||
|
import TableProMax from "@/components/table/TableProMax.vue";
|
||||||
|
import api from "@/axios";
|
||||||
|
import {TableProMaxProps} from "@/types/components/table";
|
||||||
|
import {
|
||||||
|
AssessmentRecordPagerQueryParams,
|
||||||
|
AssessmentRecordPagerVo, DeductedDetailRes,
|
||||||
|
} from "@/types/views/assessmentRecord.ts";
|
||||||
|
import {ComponentExposed} from "vue-component-type-helpers";
|
||||||
|
import { ref} from "vue";
|
||||||
|
import {Modal, TableColumnType} from "ant-design-vue";
|
||||||
|
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
|
||||||
|
type TableProps = TableProMaxProps<AssessmentRecordPagerVo,AssessmentRecordPagerQueryParams>
|
||||||
|
|
||||||
|
const open = ref<boolean>(false);
|
||||||
|
const title = ref('扣分项')
|
||||||
|
const reqApi: TableProps['requestApi'] = (params) => api.post('/assessmentRecord/pager', params) //分页
|
||||||
|
const columns: TableProps['columns'] = [
|
||||||
|
{
|
||||||
|
dataIndex: 'enterprisesUnitName',
|
||||||
|
title: '单位名称'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
customRender: ({text}) => text?.label
|
||||||
|
}, {
|
||||||
|
dataIndex: 'ckProjectName',
|
||||||
|
title: '考核项目'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'totalScore',
|
||||||
|
title: '总分'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'deductionPointsTotal',
|
||||||
|
title: '扣分',
|
||||||
|
customRender:({record})=>{
|
||||||
|
if (!record.deductionPointsTotal) {
|
||||||
|
return <a-tag color="green">0</a-tag>
|
||||||
|
}
|
||||||
|
return <a-tag class="pointer" color="red" onClick={()=>deductedDetail(record)}>{record.deductionPointsTotal}</a-tag>
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
dataIndex: 'result',
|
||||||
|
title: '得分',
|
||||||
|
customRender: ({record}) => record.totalScore - record.deductionPointsTotal
|
||||||
|
}, {
|
||||||
|
dataIndex: 'policeUnitName',
|
||||||
|
title: '考核单位'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'createUserName',
|
||||||
|
title: '考核人'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
title: '考核时间'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'remark',
|
||||||
|
title: '考核备注'
|
||||||
|
}, {
|
||||||
|
dataIndex: 'signature',
|
||||||
|
title: '签字',
|
||||||
|
customRender:({record})=>{
|
||||||
|
return <a-button onClick={()=>{
|
||||||
|
Modal.info({
|
||||||
|
title: `${record.enterprisesUnitName}${record.ckProjectName} 签字结果`,
|
||||||
|
content: () => <>
|
||||||
|
<div>审核人签字: <a-image src={record.assessmentUserSignature}/>
|
||||||
|
</div>
|
||||||
|
<div>被审核单位人员签字: <a-image src={record.byAssessmentEnterprisesUnitUserSignature}/></div>
|
||||||
|
</>
|
||||||
|
})
|
||||||
|
}}>查看</a-button>
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const TableData = [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 32,
|
||||||
|
tel: '0571-22098909',
|
||||||
|
phone: 18889898989,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
name: 'Jim Green',
|
||||||
|
tel: '0571-22098333',
|
||||||
|
phone: 18889898888,
|
||||||
|
age: 42,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 32,
|
||||||
|
tel: '0575-22098909',
|
||||||
|
phone: 18900010002,
|
||||||
|
address: 'Sidney No. 1 Lake Park',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '4',
|
||||||
|
name: 'Jim Red',
|
||||||
|
age: 18,
|
||||||
|
tel: '0575-22098909',
|
||||||
|
phone: 18900010002,
|
||||||
|
address: 'London No. 2 Lake Park',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '5',
|
||||||
|
name: 'Jake White',
|
||||||
|
age: 18,
|
||||||
|
tel: '0575-22098909',
|
||||||
|
phone: 18900010002,
|
||||||
|
address: 'Dublin No. 2 Lake Park',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const sharedOnCell = (_, index) => {
|
||||||
|
if (index === 4) {
|
||||||
|
return { colSpan: 0 };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const TableColumns: TableColumnType[] = [
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
customCell: (_, index) => ({
|
||||||
|
colSpan: index < 4 ? 1 : 5,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Age',
|
||||||
|
dataIndex: 'age',
|
||||||
|
customCell: sharedOnCell,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Home phone',
|
||||||
|
colSpan: 2,
|
||||||
|
dataIndex: 'tel',
|
||||||
|
customCell: (_, index) => {
|
||||||
|
if (index === 2) {
|
||||||
|
return { rowSpan: 2 };
|
||||||
|
}
|
||||||
|
// These two are merged into above cell
|
||||||
|
if (index === 3) {
|
||||||
|
return { rowSpan: 0 };
|
||||||
|
}
|
||||||
|
if (index === 4) {
|
||||||
|
return { colSpan: 0 };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Phone',
|
||||||
|
colSpan: 0,
|
||||||
|
dataIndex: 'phone',
|
||||||
|
customCell: sharedOnCell,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Address',
|
||||||
|
dataIndex: 'address',
|
||||||
|
customCell: sharedOnCell,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const deductedDetail = async (res:any)=>{
|
||||||
|
const {data} = await api.get<DeductedDetailRes[]>('/assessmentRecord/deductedDetail', {assessmentRecordId: res.snowFlakeId})
|
||||||
|
open.value = true
|
||||||
|
console.log(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,20 +1,37 @@
|
||||||
|
// /// <reference types="vite/client" />
|
||||||
|
|
||||||
|
// // vue3导入模块报红解决方案——找不到模块“./XXX.vue”或其相应的类型声明
|
||||||
|
// // 报错原因是:typescript 只能理解 .ts 文件,无法理解 .vue文件
|
||||||
|
// // 因此需要给.vue文件加上类型说明文件
|
||||||
|
// declare module '*.vue' {
|
||||||
|
// import type { DefineComponent } from 'vue'
|
||||||
|
// // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||||
|
// const component: DefineComponent<{}, {}, any>
|
||||||
|
// export default component
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// declare module 'lodash-es' {
|
||||||
|
// import { includes, isEmpty, ceil, divide } from 'lodash';
|
||||||
|
// export { includes, isEmpty, ceil, divide };
|
||||||
|
// }
|
||||||
|
// interface ImportMetaEnv {
|
||||||
|
// // 项目名称
|
||||||
|
// readonly VITE_APP_NAME: string;
|
||||||
|
// // 当前环境
|
||||||
|
// readonly VITE_APP_ENV: 'development' | 'production';
|
||||||
|
// // 启动端口
|
||||||
|
// readonly VITE_APP_PORT: number;
|
||||||
|
|
||||||
|
// // axios
|
||||||
|
// readonly VITE_APP_BASE_API: string;
|
||||||
|
// readonly VITE_APP_PROXY_URL: string;
|
||||||
|
|
||||||
|
// // RSA公钥
|
||||||
|
// readonly VITE_APP_RSA_PUBLIC_KEY: string;
|
||||||
|
// }
|
||||||
|
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
// vue3导入模块报红解决方案——找不到模块“./XXX.vue”或其相应的类型声明
|
|
||||||
// 报错原因是:typescript 只能理解 .ts 文件,无法理解 .vue文件
|
|
||||||
// 因此需要给.vue文件加上类型说明文件
|
|
||||||
declare module '*.vue' {
|
|
||||||
import type { DefineComponent } from 'vue'
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
|
||||||
const component: DefineComponent<{}, {}, any>
|
|
||||||
export default component
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
declare module 'lodash-es' {
|
|
||||||
import { includes, isEmpty, ceil, divide } from 'lodash';
|
|
||||||
export { includes, isEmpty, ceil, divide };
|
|
||||||
}
|
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
// 项目名称
|
// 项目名称
|
||||||
readonly VITE_APP_NAME: string;
|
readonly VITE_APP_NAME: string;
|
||||||
|
@ -22,14 +39,30 @@ interface ImportMetaEnv {
|
||||||
readonly VITE_APP_ENV: 'development' | 'production';
|
readonly VITE_APP_ENV: 'development' | 'production';
|
||||||
// 启动端口
|
// 启动端口
|
||||||
readonly VITE_APP_PORT: number;
|
readonly VITE_APP_PORT: number;
|
||||||
|
// 模块名称
|
||||||
|
readonly VITE_APP_MODULE_NAME: string;
|
||||||
|
|
||||||
// axios
|
// axios
|
||||||
readonly VITE_APP_BASE_API: string;
|
readonly VITE_APP_BASE_API: string;
|
||||||
readonly VITE_APP_PROXY_URL: string;
|
readonly VITE_APP_PROXY_URL: string;
|
||||||
|
|
||||||
|
// minio
|
||||||
|
readonly VITE_APP_MINIO_URL: string
|
||||||
|
readonly VITE_APP_MINIO_BUCKET: string
|
||||||
|
|
||||||
// RSA公钥
|
// RSA公钥
|
||||||
readonly VITE_APP_RSA_PUBLIC_KEY: string;
|
readonly VITE_APP_RSA_PUBLIC_KEY: string;
|
||||||
|
|
||||||
|
// 高德
|
||||||
|
VITE_APP_GAODE_KEY: string
|
||||||
|
VITE_APP_GAODE_VERSION: string
|
||||||
|
VITE_APP_SECURITY_JS_CODE: string
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.vue' {
|
||||||
|
import { DefineComponent, readonly } from "vue"
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,82 +1,88 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true, // 标记为复合项目的一部分 [ty-reference](1)
|
"target": "ES2020",
|
||||||
"target": "ES2020", // 设置目标 JavaScript 语言标准版本
|
"useDefineForClassFields": true,
|
||||||
"useDefineForClassFields": true, // 为类字段使用 `defineProperty`,以支持装饰器
|
"module": "ESNext",
|
||||||
"module": "ESNext", // 设置模块系统
|
"lib": [
|
||||||
"lib": [ // 指定要包含的类型库
|
"ES2020",
|
||||||
"ES2020", // 包含 ES2020 的类型定义
|
"DOM",
|
||||||
"DOM", // 包含 DOM 类型定义
|
"DOM.Iterable"
|
||||||
"DOM.Iterable" // 包含 DOM 可迭代类型定义
|
|
||||||
],
|
],
|
||||||
"skipLibCheck": true, // 忽略类型库的类型检查
|
"skipLibCheck": true,
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
"moduleResolution": "bundler", // 设置模块解析策略为 bundler 模式
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true, // 允许导入 TypeScript 扩展名
|
"allowImportingTsExtensions": true,
|
||||||
"isolatedModules": true, // 将每个文件视为一个模块
|
"isolatedModules": true,
|
||||||
"moduleDetection": "force", // 强制将所有模块视为 ESM
|
"moduleDetection": "force",
|
||||||
"noEmit": false, // 允许发出文件
|
"noEmit": true,
|
||||||
"declaration": true, // 如果需要生成 .d.ts 文件
|
"jsx": "preserve",
|
||||||
"emitDeclarationOnly": true, // 只发出声明文件,而不生成 JS 文件
|
"jsxImportSource": "vue",
|
||||||
"jsx": "preserve", // 保留 JSX 节点,不转换
|
|
||||||
"jsxImportSource": "vue", // JSX 元素来自 Vue
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": false, // 开启所有严格类型检查选项
|
"strict": false,
|
||||||
"noUnusedLocals": true, // 报告未使用的局部变量
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true, // 报告未使用的参数
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true, // 报告 switch 语句中的 fallthrough 错误
|
"noFallthroughCasesInSwitch": true,
|
||||||
"baseUrl": "./", // 设置基础模块解析目录
|
"baseUrl": "./",
|
||||||
/* 配置别名 */
|
/* 配置别名 */
|
||||||
"paths": { // 设置路径映射
|
"paths": {
|
||||||
"@/*": [ // 将 @/ 映射到 src/ 目录
|
"@/*": [
|
||||||
"./src/*"
|
"src/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"allowSyntheticDefaultImports": true // 允许默认导入
|
"allowSyntheticDefaultImports": true
|
||||||
},
|
},
|
||||||
"include": [ // 指定包含的文件
|
"include": [
|
||||||
"src/**/*.ts", // 包括 src 目录下的所有 TypeScript 文件
|
"src/**/*.ts",
|
||||||
"src/**/*.d.ts", // 包括 src 目录下的所有类型声明文件
|
"src/**/*.d.ts",
|
||||||
"src/**/*.tsx", // 包括 src 目录下的所有 JSX 文件
|
"src/**/*.tsx",
|
||||||
"src/**/*.vue", // 包括 src 目录下的所有 Vue 文件
|
"src/**/*.vue"
|
||||||
"global.d.ts"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
// // 脚手架自带 配置:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// "compilerOptions": {
|
// "compilerOptions": {
|
||||||
// "target": "ES2020",
|
// "composite": true, // 标记为复合项目的一部分 [ty-reference](1)
|
||||||
// "useDefineForClassFields": true,
|
// "target": "ES2020", // 设置目标 JavaScript 语言标准版本
|
||||||
// "module": "ESNext",
|
// "useDefineForClassFields": true, // 为类字段使用 `defineProperty`,以支持装饰器
|
||||||
// "lib": [
|
// "module": "ESNext", // 设置模块系统
|
||||||
// "ES2020",
|
// "lib": [ // 指定要包含的类型库
|
||||||
// "DOM",
|
// "ES2020", // 包含 ES2020 的类型定义
|
||||||
// "DOM.Iterable"
|
// "DOM", // 包含 DOM 类型定义
|
||||||
|
// "DOM.Iterable" // 包含 DOM 可迭代类型定义
|
||||||
// ],
|
// ],
|
||||||
// "skipLibCheck": true,
|
// "skipLibCheck": true, // 忽略类型库的类型检查
|
||||||
// /* Bundler mode */
|
// /* Bundler mode */
|
||||||
// "moduleResolution": "bundler",
|
// "moduleResolution": "bundler", // 设置模块解析策略为 bundler 模式
|
||||||
// "allowImportingTsExtensions": true,
|
// "allowImportingTsExtensions": true, // 允许导入 TypeScript 扩展名
|
||||||
// "isolatedModules": true,
|
// "isolatedModules": true, // 将每个文件视为一个模块
|
||||||
// "moduleDetection": "force",
|
// "moduleDetection": "force", // 强制将所有模块视为 ESM
|
||||||
// "noEmit": true,
|
// "noEmit": false, // 允许发出文件
|
||||||
// "jsx": "preserve",
|
// "declaration": true, // 如果需要生成 .d.ts 文件
|
||||||
|
// "emitDeclarationOnly": true, // 只发出声明文件,而不生成 JS 文件
|
||||||
|
// "jsx": "preserve", // 保留 JSX 节点,不转换
|
||||||
|
// "jsxImportSource": "vue", // JSX 元素来自 Vue
|
||||||
// /* Linting */
|
// /* Linting */
|
||||||
// "strict": true,
|
// "strict": false, // 开启所有严格类型检查选项
|
||||||
// "noUnusedLocals": true,
|
// "noUnusedLocals": true, // 报告未使用的局部变量
|
||||||
// "noUnusedParameters": true,
|
// "noUnusedParameters": true, // 报告未使用的参数
|
||||||
// "noFallthroughCasesInSwitch": true,
|
// "noFallthroughCasesInSwitch": true, // 报告 switch 语句中的 fallthrough 错误
|
||||||
// "baseUrl": "/",
|
// "baseUrl": "./", // 设置基础模块解析目录
|
||||||
// /* 配置别名 */
|
// /* 配置别名 */
|
||||||
// "paths": {
|
// "paths": { // 设置路径映射
|
||||||
// "@/*": [
|
// "@/*": [ // 将 @/ 映射到 src/ 目录
|
||||||
// "./src/*"
|
// "./src/*"
|
||||||
// ]
|
// ]
|
||||||
// },
|
// },
|
||||||
|
// "allowSyntheticDefaultImports": true // 允许默认导入
|
||||||
// },
|
// },
|
||||||
// "include": [
|
// "include": [ // 指定包含的文件
|
||||||
// "src/**/*.ts",
|
// "src/**/*.ts", // 包括 src 目录下的所有 TypeScript 文件
|
||||||
// "src/**/*.tsx",
|
// "src/**/*.d.ts", // 包括 src 目录下的所有类型声明文件
|
||||||
// "src/**/*.vue"
|
// "src/**/*.tsx", // 包括 src 目录下的所有 JSX 文件
|
||||||
|
// "src/**/*.vue", // 包括 src 目录下的所有 Vue 文件
|
||||||
|
// "global.d.ts"
|
||||||
// ]
|
// ]
|
||||||
// }
|
// }
|
|
@ -1,40 +1,43 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": "/", // 确保相对路径从根目录开始
|
|
||||||
"paths": { // 设置路径映射
|
|
||||||
"@/*": [ // 将 @/ 映射到 src/ 目录
|
|
||||||
"./src/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": [], // 可以留空,表示不显式指定任何文件
|
|
||||||
"references": [ // 引用其他 tsconfig 文件
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.app.json" // 引用 tsconfig.app.json
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.node.json" // 引用 tsconfig.node.json
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"include": [ // 指定包含的文件
|
|
||||||
"env.d.ts", // 包括环境类型的声明文件
|
|
||||||
"src/vite-env.d.ts", // 包括 Vite 环境类型的声明文件
|
|
||||||
"src/**/*.ts", // 包括 src 目录下的所有 TypeScript 文件
|
|
||||||
"src/**/*.tsx", // 包括 src 目录下的所有 JSX 文件
|
|
||||||
"src/**/*.vue", // 包括 src 目录下的所有 Vue 文件
|
|
||||||
"global.d.ts", // 确保 global.d.ts 文件被包含
|
|
||||||
"vite.config.ts" // Node 配置文件
|
|
||||||
]
|
|
||||||
}
|
|
||||||
// // 脚手架自带 配置:
|
|
||||||
// {
|
// {
|
||||||
// "files": [],
|
// "compilerOptions": {
|
||||||
// "references": [
|
// "jsx": "react",
|
||||||
// {
|
// "baseUrl": "/", // 确保相对路径从根目录开始
|
||||||
// "path": "./tsconfig.app.json"
|
// "paths": { // 设置路径映射
|
||||||
// },
|
// "@/*": [ // 将 @/ 映射到 src/ 目录
|
||||||
// {
|
// "./src/*"
|
||||||
// "path": "./tsconfig.node.json"
|
|
||||||
// }
|
|
||||||
// ]
|
// ]
|
||||||
// }
|
// }
|
||||||
|
// },
|
||||||
|
// "files": [], // 可以留空,表示不显式指定任何文件
|
||||||
|
// "references": [ // 引用其他 tsconfig 文件
|
||||||
|
// {
|
||||||
|
// "path": "./tsconfig.app.json" // 引用 tsconfig.app.json
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "./tsconfig.node.json" // 引用 tsconfig.node.json
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "include": [ // 指定包含的文件
|
||||||
|
// "env.d.ts", // 包括环境类型的声明文件
|
||||||
|
// "src/vite-env.d.ts", // 包括 Vite 环境类型的声明文件
|
||||||
|
// "src/**/*.ts", // 包括 src 目录下的所有 TypeScript 文件
|
||||||
|
// "src/**/*.tsx", // 包括 src 目录下的所有 JSX 文件
|
||||||
|
// "src/**/*.vue", // 包括 src 目录下的所有 Vue 文件
|
||||||
|
// "global.d.ts", // 确保 global.d.ts 文件被包含
|
||||||
|
// "vite.config.ts" // Node 配置文件
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// 脚手架自带 配置:
|
||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,47 +1,47 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true, // 标记为复合项目的一部分 [ty-reference](1)
|
|
||||||
"target": "ES2022", // 设置目标 JavaScript 语言标准版本
|
|
||||||
"lib": [ // 指定要包含的类型库
|
|
||||||
"ES2023" // 包含 ES2023 的类型定义
|
|
||||||
],
|
|
||||||
"module": "ESNext", // 设置模块系统
|
|
||||||
"skipLibCheck": true, // 忽略类型库的类型检查
|
|
||||||
/* Bundler mode */
|
|
||||||
"moduleResolution": "bundler", // 设置模块解析策略为 bundler 模式
|
|
||||||
"allowImportingTsExtensions": true, // 允许导入 TypeScript 扩展名
|
|
||||||
"isolatedModules": true, // 将每个文件视为一个模块
|
|
||||||
"moduleDetection": "force", // 强制将所有模块视为 ESM
|
|
||||||
"noEmit": false, // 允许发出文件
|
|
||||||
"declaration": true, // 如果需要生成 .d.ts 文件
|
|
||||||
"emitDeclarationOnly": true, // 只发出声明文件,而不生成 JS 文件
|
|
||||||
"strict": true, // 开启所有严格类型检查选项
|
|
||||||
"noUnusedLocals": true, // 报告未使用的局部变量
|
|
||||||
"noUnusedParameters": true, // 报告未使用的参数
|
|
||||||
"noFallthroughCasesInSwitch": true // 报告 switch 语句中的 fallthrough 错误
|
|
||||||
},
|
|
||||||
"include": [ // 指定包含的文件
|
|
||||||
"vite.config.ts" // 包括 Vite 配置文件
|
|
||||||
]
|
|
||||||
}
|
|
||||||
// 脚手架自带 配置:
|
|
||||||
// {
|
// {
|
||||||
// "compilerOptions": {
|
// "compilerOptions": {
|
||||||
// "target": "ES2022",
|
// "composite": true, // 标记为复合项目的一部分 [ty-reference](1)
|
||||||
// "lib": ["ES2023"],
|
// "target": "ES2022", // 设置目标 JavaScript 语言标准版本
|
||||||
// "module": "ESNext",
|
// "lib": [ // 指定要包含的类型库
|
||||||
// "skipLibCheck": true,
|
// "ES2023" // 包含 ES2023 的类型定义
|
||||||
|
// ],
|
||||||
|
// "module": "ESNext", // 设置模块系统
|
||||||
|
// "skipLibCheck": true, // 忽略类型库的类型检查
|
||||||
// /* Bundler mode */
|
// /* Bundler mode */
|
||||||
// "moduleResolution": "bundler",
|
// "moduleResolution": "bundler", // 设置模块解析策略为 bundler 模式
|
||||||
// "allowImportingTsExtensions": true,
|
// "allowImportingTsExtensions": true, // 允许导入 TypeScript 扩展名
|
||||||
// "isolatedModules": true,
|
// "isolatedModules": true, // 将每个文件视为一个模块
|
||||||
// "moduleDetection": "force",
|
// "moduleDetection": "force", // 强制将所有模块视为 ESM
|
||||||
// "noEmit": true,
|
// "noEmit": false, // 允许发出文件
|
||||||
// /* Linting */
|
// "declaration": true, // 如果需要生成 .d.ts 文件
|
||||||
// "strict": true,
|
// "emitDeclarationOnly": true, // 只发出声明文件,而不生成 JS 文件
|
||||||
// "noUnusedLocals": true,
|
// "strict": true, // 开启所有严格类型检查选项
|
||||||
// "noUnusedParameters": true,
|
// "noUnusedLocals": true, // 报告未使用的局部变量
|
||||||
// "noFallthroughCasesInSwitch": true
|
// "noUnusedParameters": true, // 报告未使用的参数
|
||||||
|
// "noFallthroughCasesInSwitch": true // 报告 switch 语句中的 fallthrough 错误
|
||||||
// },
|
// },
|
||||||
// "include": ["vite.config.ts"]
|
// "include": [ // 指定包含的文件
|
||||||
|
// "vite.config.ts" // 包括 Vite 配置文件
|
||||||
|
// ]
|
||||||
// }
|
// }
|
||||||
|
// 脚手架自带 配置:
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
|
@ -14,7 +14,11 @@ export default defineConfig(({ mode }) => {
|
||||||
define: {
|
define: {
|
||||||
__APP_ENV: JSON.stringify(env)
|
__APP_ENV: JSON.stringify(env)
|
||||||
},
|
},
|
||||||
base: '/',
|
// base: './',
|
||||||
|
base: '/policeManagement/',
|
||||||
|
// base: '/',
|
||||||
|
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
|
@ -45,7 +49,7 @@ export default defineConfig(({ mode }) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: 'dist',
|
outDir: 'policeManagement',
|
||||||
target: 'modules',
|
target: 'modules',
|
||||||
chunkSizeWarningLimit: 1500,
|
chunkSizeWarningLimit: 1500,
|
||||||
minify: 'terser',
|
minify: 'terser',
|
||||||
|
|
|
@ -3,3 +3,4 @@ target
|
||||||
logs
|
logs
|
||||||
temp
|
temp
|
||||||
HELP.md
|
HELP.md
|
||||||
|
rebel.xml
|
|
@ -0,0 +1,56 @@
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
tools {
|
||||||
|
jdk "jdk-17.0.11"
|
||||||
|
maven "apache-maven-3.8.8"
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('拉取代码') {
|
||||||
|
steps {
|
||||||
|
echo '开始拉取代码'
|
||||||
|
checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: '3', url: 'http://175.6.124.250:3100/luozhun/policeSecurity.git']])
|
||||||
|
echo '代码拉取成功'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('构建后台服务') {
|
||||||
|
steps{
|
||||||
|
echo '开始构建后台服务'
|
||||||
|
sh 'cd /var/jenkins_home/workspace/警保联动后端服务/policeSecurityServer && mvn clean -DskipTests=true package -P prod'
|
||||||
|
echo '后台服务构建完成'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('ssh远程推送代码'){
|
||||||
|
steps{
|
||||||
|
echo '开始推送构建产物'
|
||||||
|
script{
|
||||||
|
def remote = [:]
|
||||||
|
remote.name = 'server-118.253.177.137'
|
||||||
|
remote.host = '118.253.177.137'
|
||||||
|
remote.port = 55555
|
||||||
|
remote.allowAnyHosts = true
|
||||||
|
withCredentials([usernamePassword(credentialsId: '4', passwordVariable: 'password', usernameVariable: 'username')]) {
|
||||||
|
remote.user = "${username}"
|
||||||
|
remote.password = "${password}"
|
||||||
|
}
|
||||||
|
sshCommand remote: remote, command: 'pwd=$(pwd) echo "ssh连接成功!当前工作目录:$(pwd)"'
|
||||||
|
|
||||||
|
sshCommand remote: remote, command: 'echo "停止后台服务..."'
|
||||||
|
sshCommand remote: remote, command: '''docker stop policeSecurityServer'''
|
||||||
|
sshCommand remote: remote, command: 'echo "后台服务已停止..."'
|
||||||
|
|
||||||
|
sshCommand remote: remote, command: 'echo "删除原来的server.jar..."'
|
||||||
|
sshRemove remote: remote, path: '/home/javaProject/policeSecurity/policeSecurityServer.jar'
|
||||||
|
sshCommand remote: remote, command: 'echo "server.jar删除成功!"'
|
||||||
|
|
||||||
|
sshCommand remote: remote, command: 'echo "将构建的server.jar发送到服务器..."'
|
||||||
|
sshPut remote: remote, from: '/var/jenkins_home/workspace/警保联动后端服务/policeSecurityServer/target/policeSecurityServer.jar', into: '/home/javaProject/policeSecurity'
|
||||||
|
sshCommand remote: remote, command: 'echo "server.jar发送成功!"'
|
||||||
|
|
||||||
|
sshCommand remote: remote, command: 'echo "启动后台服务..."'
|
||||||
|
sshCommand remote: remote, command: '''docker start policeSecurityServer'''
|
||||||
|
sshCommand remote: remote, command: 'echo "后台服务启动成功!"'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@
|
||||||
<easyexcel.version>3.3.4</easyexcel.version>
|
<easyexcel.version>3.3.4</easyexcel.version>
|
||||||
<mysql.driver.version>8.0.32</mysql.driver.version>
|
<mysql.driver.version>8.0.32</mysql.driver.version>
|
||||||
<mybatis.plus.version>3.5.7</mybatis.plus.version>
|
<mybatis.plus.version>3.5.7</mybatis.plus.version>
|
||||||
|
<geotools.version>25.2</geotools.version>
|
||||||
<druid.version>1.2.20</druid.version>
|
<druid.version>1.2.20</druid.version>
|
||||||
<minio.version>8.4.3</minio.version>
|
<minio.version>8.4.3</minio.version>
|
||||||
<okhttp.version>4.8.1</okhttp.version>
|
<okhttp.version>4.8.1</okhttp.version>
|
||||||
|
@ -190,6 +191,17 @@
|
||||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
<version>${mybatis.plus.version}</version>
|
<version>${mybatis.plus.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 处理地理空间数据的读取、写入、转换、分析以及可视化 geotools-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.geotools</groupId>
|
||||||
|
<artifactId>gt-main</artifactId>
|
||||||
|
<version>${geotools.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.geotools</groupId>
|
||||||
|
<artifactId>gt-geojson</artifactId>
|
||||||
|
<version>${geotools.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- minio对象存储 https://www.minio.org.cn/ -->
|
<!-- minio对象存储 https://www.minio.org.cn/ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.minio</groupId>
|
<groupId>io.minio</groupId>
|
||||||
|
|