小程序

This commit is contained in:
wangyilin 2024-09-11 09:22:00 +08:00
parent 2fc5a867fb
commit cab07c803f
17 changed files with 255 additions and 65 deletions

View File

@ -2,7 +2,7 @@
"name": "collect_information", "name": "collect_information",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"description": "智慧派出所信息采集小程序", "description": "小程序",
"templateInfo": { "templateInfo": {
"name": "default", "name": "default",
"typescript": true, "typescript": true,

View File

@ -2,7 +2,8 @@ export default defineAppConfig({
pages: [ pages: [
'pages/login/login', 'pages/login/login',
'pages/register/register', 'pages/register/register',
'pages/index/index', 'pages/projectManager/index/index',
'pages/policeManager/index/index',
'pages/mine/mine', 'pages/mine/mine',
'pages/employeeInfo/employeeInfo', 'pages/employeeInfo/employeeInfo',
], ],
@ -15,7 +16,7 @@ export default defineAppConfig({
tabBar: { tabBar: {
list: [ list: [
{ {
pagePath: 'pages/index/index', pagePath: 'pages/projectManager/index/index',
text: '首页', text: '首页',
iconPath: "assets/mine/punch.png", iconPath: "assets/mine/punch.png",
selectedIconPath: "assets/mine/punch-active.png" selectedIconPath: "assets/mine/punch-active.png"

View File

@ -1,22 +0,0 @@
<template>
<view>
<view class="swiper-demo">
12
</view>
<view class="margin-top">
45
</view>
</view>
</template>
<script setup lang="ts">
import './index.scss'
import {ref} from 'vue'
import Taro from "@tarojs/taro";
const swiperRef = ref()
console.log(swiperRef)
</script>

View File

@ -0,0 +1,87 @@
.SignMultiple {
height: 100vh;
background: #f4f5f7;
position: relative;
.urlIndex {
display: flex;
justify-content: center;
align-items: center;
padding: 0;
margin: 0;
width: 100%;
height: 440rpx;
background: #3a6bbe;
text-align: center;
overflow: hidden;
.urlTitle {
width: 100%;
height: 300rpx;
.urlWelcome {
color: #fff;
font-size: 24px;
}
.urlHibiscus {
height: 200rpx;
line-height: 58rpx;
//font-size: 38rpx;
margin: 40rpx 20rpx;
border: 2px solid #a1b8e0;
display: flex;
justify-content: center;
.contact {
height: 100rpx;
width: 100rpx;
border-radius: 50%;
border: solid 1px gray;
.image {
width: 100%;
height: 100%;
border-radius: 50%
}
}
}
}
}
.type {
margin: 0 20rpx 0 20rpx;
width: 29%;
text-align: right;
}
.HiddenEse {
position: absolute;
top: 4px;
right: 0;
width: 76rpx;
height: 40rpx;
image {
width: 40rpx;
height: 40rpx;
}
}
.SignItem {
transform: translateY(15%);
display: flex;
flex-direction: column;
margin: 20rpx 48rpx;
border-radius: 20rpx;
}
.Cancel {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
margin: 20rpx 40rpx;
}
}

View File

@ -1,16 +1,71 @@
<template> <template>
<view class="SignMultiple"> <view class="SignMultiple">
登录 <view class="urlIndex">
<view class="urlTitle">
<view class="urlWelcome">
<view style="font-size: 26px">Welcome</view>
<view class="urlHibiscus">
<view class="contact">
<image
src='https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png'
mode="scaleToFill"
class="image"
/>
<text>欢迎</text>
</view>
</view>
</view>
</view>
</view>
<view class="SignItem">
<view class="Cancel">
<nut-button block type="success" @click="onLogin">一键授权</nut-button>
</view>
</view>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import "./login.scss"; import "./login.scss";
import Taro, { useLoad } from "@tarojs/taro"; import Taro, { useLoad } from "@tarojs/taro";
import api from "@/request/index";
useLoad(() => {
}); useLoad(() => {});
const onLogin = () => {
Taro.login({
success: (res) => {
if(res.code){
api.post<LoginUserInfo>("/login", {
clientType: 'MINI_PROGRAM',
loginParams: {
code:res.code
}
}).then(async (resp)=>{
await Taro.setStorage({
key: "token",
data: resp.data,
success(res) {
Taro.switchTab({
url: '/pages/projectManager/index/index'
})
},
})
}).catch((error)=>{
if(error.code === 402){
Taro.navigateTo({
url: "/pages/register/register",
});
}
})
}
},
});
};
</script> </script>

View File

@ -0,0 +1,12 @@
<template>
<view>警察</view>
</template>
<script setup lang="ts">
</script>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,41 @@
<template>
<view>
<view class="swiper-demo">
<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: 150px">
<img :src="item" alt="" style="height: 100%; width: 100%" draggable="false"/>
</nut-swiper-item>
</nut-swiper>
</view>
<view class="margin-top">
<nut-grid :column-num="3">
<nut-grid-item
text="我的项目"
@click="Taro.navigateTo({url: '/pages/index/dataEntry/buildFloorEntry/buildFloorEntry'})">
</nut-grid-item>
<nut-grid-item
text="警保风采"
@click="Taro.navigateTo({url: '/pages/index/dataEntry/personnelInformationEntry/personnelInformationEntry'})">
</nut-grid-item>
<nut-grid-item text=".....">
</nut-grid-item>
</nut-grid>
</view>
</view>
</template>
<script setup lang="ts">
import './index.scss'
import {ref} from 'vue'
import Taro from "@tarojs/taro";
const list = ref([
'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
'https://storage.360buyimg.com/jdc-article/fristfabu.jpg'
])
const swiperRef = ref()
</script>

View File

@ -24,18 +24,6 @@
</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">
<view @click="visible = true" style="color: black">
{{ streetCommunitySmallCommunityLabel || "请选择行政区划" }}
</view>
</nut-form-item>
<nut-form-item label="身份:"> <nut-form-item label="身份:">
<nut-radio-group v-model="formData.identity"> <nut-radio-group v-model="formData.identity">
<nut-radio <nut-radio
@ -46,8 +34,20 @@
</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">
<view @click="visible = true" style="color: #808080">
{{ streetCommunitySmallCommunityLabel || "请选择行政区划" }}
</view>
</nut-form-item>
<nut-form-item label="单位:" name="unitId"> <nut-form-item label="单位:" name="unitId">
<view @click="unitsList" style="color: black"> <view @click="unitsList" style="color: #808080">
{{ selectedLabel || '请选择单位'}} {{ selectedLabel || '请选择单位'}}
</view> </view>
</nut-form-item> </nut-form-item>
@ -65,7 +65,7 @@
:field-names="{ :field-names="{
text: 'label', text: 'label',
children: 'extData' children: 'extData'
}" v-model="formData.unitId" :columns="columns" title="请选择城市" @confirm="confirm" @cancel="show = false"/> }" v-model="formData.unitId" :columns="columns" title="请选择单位" @confirm="confirm" @cancel="show = false"/>
</nut-popup> </nut-popup>
<view class="registerBtn"> <view class="registerBtn">
<nut-button block type="success" @click="register">注册</nut-button> <nut-button block type="success" @click="register">注册</nut-button>
@ -75,7 +75,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import './register.scss' import './register.scss'
import {onMounted, ref} from "vue"; import {onMounted, ref, watch} from "vue";
import {IDENTITY, SEX} from "@/enums"; import {IDENTITY, SEX} from "@/enums";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import api from '@/request/index' import api from '@/request/index'
@ -121,16 +121,22 @@ const unitsList = async () => {
} }
} }
const selectedLabel = ref ('') const selectedLabel = ref ('')
const confirm = ({selectedOptions, selectedValue}) => { const confirm = ({selectedOptions, selectedValue}) => {
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
}) })
console.log(formData.value.unitId,selectedLabel.value)
show.value = false show.value = false
} }
//
watch(()=>formData.value.identity,(value)=>{
formData.value.unitId = ''
selectedLabel.value = ''
})
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
// logincode // logincode
// //
@ -157,8 +163,8 @@ const register = async () => {
key: "token", key: "token",
data: resp.data, data: resp.data,
success(res) { success(res) {
Taro.switchTab({ Taro.navigateTo({
url: '/pages/index/index' url: '/pages/login/login'
}) })
}, },
}) })
@ -205,8 +211,8 @@ const getNickname = (e) => {
console.log( formData.value.name) console.log( formData.value.name)
} }
onMounted(() => { onMounted(async () => {
getAdministrativeDivisionTree() await getAdministrativeDivisionTree()
}) })
</script> </script>

View File

@ -2,3 +2,4 @@ interface LoginUserInfo {
name?: string; name?: string;
avatar?: string; avatar?: string;
} }

View File

@ -7,7 +7,7 @@
:src="minioBaseUrl+modelValue" :src="minioBaseUrl+modelValue"
alt="avatar"/> alt="avatar"/>
<a-button class="btn-success" @click="selectFile">{{ btnLabel }}</a-button> <a-button class="btn-success" @click="selectFile">{{ btnLabel }}</a-button>
<input id="myFileInput" type="file" style="display: none"/> <input id="myFileInput" type="file" style="display: none" ref="fileInput" />
</div> </div>
</template> </template>
@ -40,6 +40,8 @@ const props = withDefaults(defineProps<{
const uploading = ref(false) const uploading = ref(false)
const percent = ref(0) const percent = ref(0)
let cancelToken: CancelTokenSource | null = null let cancelToken: CancelTokenSource | null = null
const uploadUrl = ref()
const fileInput = ref(null);
const selectFile = () => { const selectFile = () => {
document.getElementById('myFileInput')?.click() document.getElementById('myFileInput')?.click()
@ -62,19 +64,23 @@ async function inputFileListener(this: HTMLInputElement) {
uploading.value = true; uploading.value = true;
const objectName = generateSimpleObjectName(selectedFile.name, props.parentDir) const objectName = generateSimpleObjectName(selectedFile.name, props.parentDir)
const uploadUrl = await getResignedObjectUrl(__APP_ENV.VITE_APP_MINIO_BUCKET, objectName); uploadUrl.value = await getResignedObjectUrl(__APP_ENV.VITE_APP_MINIO_BUCKET, objectName)
cancelToken = axios.CancelToken.source() cancelToken = axios.CancelToken.source()
await axios.put(uploadUrl, selectedFile, { await axios.put(uploadUrl.value, selectedFile, {
cancelToken: cancelToken.token, cancelToken: cancelToken.token,
onUploadProgress: (progressEvent) => { onUploadProgress: (progressEvent) => {
percent.value = (progressEvent.loaded / (progressEvent.total as number) * 100 | 0) percent.value = (progressEvent.loaded / (progressEvent.total as number) * 100 | 0)
} }
}) })
modelValue.value = '/' + __APP_ENV.VITE_APP_MINIO_BUCKET + objectName; modelValue.value = '/' + __APP_ENV.VITE_APP_MINIO_BUCKET + objectName;
uploading.value = false; uploading.value = false;
} }
const fileDelete = ()=>{
uploadUrl.value = ''
fileInput.value.value = ''
modelValue.value = ''
}
onMounted(() => { onMounted(() => {
document.getElementById('myFileInput')?.addEventListener('change', inputFileListener); document.getElementById('myFileInput')?.addEventListener('change', inputFileListener);
}) })
@ -82,6 +88,7 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
document.getElementById('myFileInput')?.removeEventListener('change', inputFileListener); document.getElementById('myFileInput')?.removeEventListener('change', inputFileListener);
}) })
defineExpose({fileDelete})
</script> </script>

View File

@ -4,7 +4,7 @@ export interface formDatePort {
businessLicense:string, businessLicense:string,
legalPersonInfo:string, legalPersonInfo:string,
telephone:string, telephone:string,
administrativeDivisionCodes:Record<string, any>, administrativeDivisionCodes:string,
address:string, address:string,
nature:string nature:string
} }

View File

@ -91,7 +91,7 @@ const formDate = ref<formDatePort>({
businessLicense:'', businessLicense:'',
legalPersonInfo:'', legalPersonInfo:'',
telephone:'', telephone:'',
administrativeDivisionCodes:undefined, administrativeDivisionCodes:'',
address:'', address:'',
nature:'' nature:''
}) })
@ -126,13 +126,12 @@ const DivisionTree = async ()=>{
// 2 // 2
const filter: ShowSearchType['filter'] = (inputValue, path) => { const filter: ShowSearchType['filter'] = (inputValue, path) => {
console.log(inputValue,path)
return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1); return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
}; };
// //
const searchAdministrativeDivisionTree = (e:Array<string>)=>{ const searchAdministrativeDivisionTree = (e:Array<string>)=>{
formDate.value.administrativeDivisionCodes = e formDate.value.administrativeDivisionCodes = e as any
} }
// //
const onFinish = async ()=>{ const onFinish = async ()=>{
@ -153,6 +152,7 @@ const onFinish = async ()=>{
} }
const resp = await api.post('/common/securityUnitRegister',securityUnitRegisterParams) const resp = await api.post('/common/securityUnitRegister',securityUnitRegisterParams)
message.success(resp.message) message.success(resp.message)
fileUpload.value.fileDelete()
await formDateRef.value.resetFields() // await formDateRef.value.resetFields() //
formDate.value = { formDate.value = {
name:'', name:'',
@ -160,7 +160,7 @@ const onFinish = async ()=>{
businessLicense:'', businessLicense:'',
legalPersonInfo:'', legalPersonInfo:'',
telephone:'', telephone:'',
administrativeDivisionCodes:undefined, administrativeDivisionCodes:'',
address:'', address:'',
nature:'' nature:''
} }

View File

@ -98,8 +98,8 @@ const formParams = ref<{
const columns: TableProps['columns'] = [ const columns: TableProps['columns'] = [
{ {
dataIndex: 'enterprisesUnitName', dataIndex: 'name',
title: '企事业单位名称', title: '服务项目名称',
width: 150, width: 150,
ellipsis: true ellipsis: true
}, },
@ -108,9 +108,10 @@ const columns: TableProps['columns'] = [
title: '项目经理小程序用户名称', title: '项目经理小程序用户名称',
width: 200, width: 200,
ellipsis: true ellipsis: true
}, { },
dataIndex: 'name', {
title: '服务项目名称', dataIndex: 'enterprisesUnitName',
title: '企事业单位名称',
width: 150, width: 150,
ellipsis: true ellipsis: true
}, },
@ -129,7 +130,7 @@ const columns: TableProps['columns'] = [
{ {
dataIndex:'idNumber', dataIndex:'idNumber',
title: '证件号', title: '证件号',
width:200 width:170
}, },
{ {
dataIndex:'serviceArea', dataIndex:'serviceArea',
@ -426,8 +427,8 @@ const addServiceProjects = () => {
} }
onMounted(async ()=>{ onMounted(async ()=>{
await getAdministrativeDivisionTree()
await projectManagerMiniProgram() await projectManagerMiniProgram()
await getAdministrativeDivisionTree()
}) })
</script> </script>

View File

@ -98,6 +98,7 @@ const columns: TableProps['columns'] = [
} }
return <a-space > return <a-space >
<a-button <a-button
type="primary"
className={record.isEnable.value === 0 ? 'btn-danger' : 'btn-success'} className={record.isEnable.value === 0 ? 'btn-danger' : 'btn-success'}
onClick={async () => { onClick={async () => {
const resp = await api.post('/management/disableOrEnableMiniProgramUser', { const resp = await api.post('/management/disableOrEnableMiniProgramUser', {