完成:黄家明项目的开发并存档

This commit is contained in:
2025-06-18 15:58:26 +08:00
parent 26db77ee12
commit f83b856438
7 changed files with 233 additions and 197 deletions

View File

@@ -1,4 +1,4 @@
import type { PageParam } from '@/api'; import type { PageParam } from '@/api/index';
/** /**
* 用户 * 用户
@@ -15,6 +15,8 @@ export interface UserRole {
updateTime?: string; updateTime?: string;
// 角色名称 // 角色名称
roleName?: string; roleName?: string;
// 角色标识
roleCode?: string;
// 租户ID // 租户ID
tenantId?: number; tenantId?: number;
} }

View File

@@ -12,7 +12,7 @@ import type {
*/ */
export async function pageWebsiteField(params: CmsWebsiteFieldParam) { export async function pageWebsiteField(params: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsiteField>>>( const res = await request.get<ApiResult<PageResult<CmsWebsiteField>>>(
'/cms/website-field/page', '/cms/cms-website-field/page',
{ {
params params
} }
@@ -28,7 +28,7 @@ export async function pageWebsiteField(params: CmsWebsiteFieldParam) {
*/ */
export async function listWebsiteField(params?: CmsWebsiteFieldParam) { export async function listWebsiteField(params?: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<CmsWebsiteField[]>>( const res = await request.get<ApiResult<CmsWebsiteField[]>>(
'https://modules.gxwebsoft.com/api/cms/website-field', '/cms/cms-website-field',
{ {
params params
} }
@@ -44,7 +44,7 @@ export async function listWebsiteField(params?: CmsWebsiteFieldParam) {
*/ */
export async function getWebsiteField(id: number) { export async function getWebsiteField(id: number) {
const res = await request.get<ApiResult<CmsWebsiteField>>( const res = await request.get<ApiResult<CmsWebsiteField>>(
'/cms/website-field/' + id '/cms/cms-website-field/' + id
); );
if (res.code === 0 && res.data) { if (res.code === 0 && res.data) {
return res.data; return res.data;
@@ -57,7 +57,7 @@ export async function getWebsiteField(id: number) {
*/ */
export async function addWebsiteField(data: CmsWebsiteField) { export async function addWebsiteField(data: CmsWebsiteField) {
const res = await request.post<ApiResult<unknown>>( const res = await request.post<ApiResult<unknown>>(
'/cms/website-field', '/cms/cms-website-field',
data data
); );
if (res.code === 0) { if (res.code === 0) {
@@ -71,7 +71,7 @@ export async function addWebsiteField(data: CmsWebsiteField) {
*/ */
export async function updateWebsiteField(data: CmsWebsiteField) { export async function updateWebsiteField(data: CmsWebsiteField) {
const res = await request.put<ApiResult<unknown>>( const res = await request.put<ApiResult<unknown>>(
'/cms/website-field', '/cms/cms-website-field',
data data
); );
if (res.code === 0) { if (res.code === 0) {
@@ -85,7 +85,7 @@ export async function updateWebsiteField(data: CmsWebsiteField) {
*/ */
export async function removeWebsiteField(id?: number) { export async function removeWebsiteField(id?: number) {
const res = await request.del<ApiResult<unknown>>( const res = await request.del<ApiResult<unknown>>(
'/cms/website-field/' + id '/cms/cms-website-field/' + id
); );
if (res.code === 0) { if (res.code === 0) {
return res.message; return res.message;
@@ -98,7 +98,7 @@ export async function removeWebsiteField(id?: number) {
*/ */
export async function removeBatchWebsiteField(data: (number | undefined)[]) { export async function removeBatchWebsiteField(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>( const res = await request.del<ApiResult<unknown>>(
'/cms/website-field/batch', '/cms/cms-website-field/batch',
{ {
data data
} }
@@ -118,7 +118,7 @@ export async function checkExistence(
id?: number id?: number
) { ) {
const res = await request.get<ApiResult<unknown>>( const res = await request.get<ApiResult<unknown>>(
'/cms/website-field/existence', '/cms/cms-website-field/existence',
{ {
params: { field, value, id } params: { field, value, id }
} }
@@ -134,7 +134,7 @@ export async function checkExistence(
*/ */
export async function configWebsiteField(params?: CmsWebsiteFieldParam) { export async function configWebsiteField(params?: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<Config>>( const res = await request.get<ApiResult<Config>>(
'https://modules.gxwebsoft.com/api/cms/website-field/config', 'https://modules.gxwebsoft.com/api/cms/cms-website-field/config',
{ {
params params
} }

View File

@@ -10,8 +10,8 @@ import {mqttStart} from "@/api/hjm/hjmCar";
function App(props) { function App(props) {
const reload = () => { const reload = () => {
mqttStart().then(res => { mqttStart().then(() => {
console.log(res, 'mqttStart') console.log('mqttStart')
}) })
Taro.login({ Taro.login({
success: (res) => { success: (res) => {

View File

@@ -14,6 +14,7 @@ import {HjmBxLog} from "@/api/hjm/hjmBxLog/model";
import {HjmCar} from "@/api/hjm/hjmCar/model"; import {HjmCar} from "@/api/hjm/hjmCar/model";
import {listCmsWebsiteField} from "@/api/cms/cmsWebsiteField"; import {listCmsWebsiteField} from "@/api/cms/cmsWebsiteField";
import {CmsWebsiteField} from "@/api/cms/cmsWebsiteField/model"; import {CmsWebsiteField} from "@/api/cms/cmsWebsiteField/model";
import {TenantId} from "@/utils/config";
// 图片数据接口 // 图片数据接口
interface UploadedImageData { interface UploadedImageData {
@@ -126,7 +127,6 @@ function BxAdd() {
// 上传单张图片 // 上传单张图片
const uploadSingleImage = (filePath: string, index: number) => { const uploadSingleImage = (filePath: string, index: number) => {
const TenantId = Taro.getStorageSync('TenantId')
Taro.uploadFile({ Taro.uploadFile({
url: 'https://server.gxwebsoft.com/api/oss/upload', url: 'https://server.gxwebsoft.com/api/oss/upload',

View File

@@ -3,7 +3,7 @@ import Taro, {useRouter} from '@tarojs/taro'
import {getHjmCarByCode, pageHjmCar, updateHjmCar} from "@/api/hjm/hjmCar"; import {getHjmCarByCode, pageHjmCar, updateHjmCar} from "@/api/hjm/hjmCar";
import {HjmCar} from "@/api/hjm/hjmCar/model"; import {HjmCar} from "@/api/hjm/hjmCar/model";
import './location.scss'; import './location.scss';
import { Swiper } from '@nutui/nutui-react-taro' import {Swiper} from '@nutui/nutui-react-taro'
import {copyText} from "@/utils/common"; import {copyText} from "@/utils/common";
import {View} from '@tarojs/components' import {View} from '@tarojs/components'
import { import {
@@ -14,14 +14,13 @@ import {
Cell, Cell,
Image Image
} from '@nutui/nutui-react-taro' } from '@nutui/nutui-react-taro'
import { ImagePreview } from '@nutui/nutui-react-taro' import {ImagePreview} from '@nutui/nutui-react-taro'
import {Scan} from '@nutui/icons-react-taro' import {Scan} from '@nutui/icons-react-taro'
import {pageDictData} from "@/api/system/dict-data"; import {pageDictData} from "@/api/system/dict-data";
import {DictData} from "@/api/system/dict-data/model"; import {DictData} from "@/api/system/dict-data/model";
import {myUserVerify} from "@/api/system/userVerify"; import {myUserVerify} from "@/api/system/userVerify";
import {listUserRole, updateUserRole} from "@/api/system/userRole"; import {listUserRole} from "@/api/system/userRole";
import {UserRole} from "@/api/system/userRole/model"; import {TenantId} from "@/utils/config";
import {updateUser} from "@/api/system/user";
// 图片数据接口 // 图片数据接口
interface UploadedImageData { interface UploadedImageData {
@@ -41,10 +40,9 @@ const Query = () => {
const {params} = useRouter(); const {params} = useRouter();
const [keywords, setKeywords] = useState<string>() const [keywords, setKeywords] = useState<string>()
const [dict, setDict] = useState<DictData[]>([]) const [dict, setDict] = useState<DictData[]>([])
const [adminId, setAdminId] = useState<number>() const [claimVehicle, setClaimVehicle] = useState<boolean>(false)
const [showPreview, setShowPreview] = useState(false) const [showPreview, setShowPreview] = useState(false)
const [disabled, setDisabled] = useState<boolean>(false) const [disabled, setDisabled] = useState<boolean>(false)
const [userRole, setUserRole] = useState<UserRole>()
const [fileList, setFileList] = useState<UploadedImageData[]>([]) // 图片文件列表 const [fileList, setFileList] = useState<UploadedImageData[]>([]) // 图片文件列表
const [FormData, setFormData] = useState<HjmCar>( const [FormData, setFormData] = useState<HjmCar>(
{ {
@@ -108,55 +106,40 @@ const Query = () => {
// 提交表单 // 提交表单
const submitSucceed = (values: any) => { const submitSucceed = (values: any) => {
// 禁用按钮 // 禁用按钮
if(disabled){ if (disabled) {
return false; return false;
} }
console.log(values) console.log(values)
if(FormData.image == '[]' || !FormData.image){ if (FormData.image == '[]' || !FormData.image) {
Taro.showToast({ Taro.showToast({
title: '请上传车辆图片', title: '请上传车辆图片',
icon: 'error' icon: 'error'
}); });
return false // return false
} }
if(!FormData.gpsNo){ if (!FormData.gpsNo) {
Taro.showToast({ Taro.showToast({
title: '请绑定GPS', title: '请绑定GPS',
icon: 'error' icon: 'error'
}); });
return false return false
} }
// 升级为快递员
if(userRole){ // 安装车辆
updateHjmCar({ updateHjmCar({
...FormData, ...FormData,
status: 1, status: 1
driverId: adminId, }).then(() => {
driverName: Taro.getStorageSync('RealName') Taro.showToast({title: `绑定成功`, icon: 'success'})
}).then(() => { setTimeout(() => {
Taro.showToast({title: `绑定成功`, icon: 'success'}) return Taro.navigateBack()
// 变更角色 }, 1000)
if (Taro.getStorageSync('OrganizationParentId') > 0) { }).catch((err) => {
userRole.roleId = 1738; Taro.showToast({
updateUserRole(userRole).then(() => { title: err.message,
Taro.showToast({title: `绑定成功`, icon: 'success'}) icon: 'none'
}) });
updateUser({ })
userId: Taro.getStorageSync('UserId'),
organizationId: FormData.organizationId
}).then(() => {})
}
setTimeout(() => {
reload();
return Taro.navigateBack()
}, 1000)
}).catch(() => {
Taro.showToast({
title: '绑定失败',
icon: 'error'
});
})
}
} }
const submitFailed = (error: any) => { const submitFailed = (error: any) => {
@@ -174,7 +157,7 @@ const Query = () => {
gpsNo: res.result gpsNo: res.result
}); });
Taro.showToast({ Taro.showToast({
title: '扫码成功' + res.result, title: res.result,
icon: 'success', icon: 'success',
duration: 2000 duration: 2000
}); });
@@ -192,6 +175,13 @@ const Query = () => {
// 选择并上传图片 // 选择并上传图片
const handleChooseImage = () => { const handleChooseImage = () => {
if (disabled) {
Taro.showToast({
title: '您不是安装人员',
icon: 'error'
});
return false;
}
if (fileList.length >= 5) { if (fileList.length >= 5) {
Taro.showToast({ Taro.showToast({
title: '最多只能上传5张图片', title: '最多只能上传5张图片',
@@ -224,7 +214,6 @@ const Query = () => {
// 上传单张图片 // 上传单张图片
const uploadSingleImage = (filePath: any, index: number) => { const uploadSingleImage = (filePath: any, index: number) => {
const TenantId = Taro.getStorageSync('TenantId')
Taro.uploadFile({ Taro.uploadFile({
url: 'https://server.gxwebsoft.com/api/oss/upload', url: 'https://server.gxwebsoft.com/api/oss/upload',
@@ -318,108 +307,128 @@ const Query = () => {
} }
} }
// 打开地图选择位置 // 认领车辆
// const chooseLocation = async () => { const onClaimVehicle = () => {
// try { updateHjmCar({
// const res = await Taro.chooseLocation({ ...FormData,
// latitude, // 默认纬度 status: 2,
// longitude // 默认经度 driverId: Taro.getStorageSync('UserId'),
// }) driverName: Taro.getStorageSync('RealName')
// console.log('选择的位置:', res); }).then(() => {
// } catch (err) { Taro.showToast({title: `认领成功`, icon: 'success'})
// console.error('选择位置失败:', err); setTimeout(() => {
// } return Taro.navigateBack()
// } }, 1000)
const reload = () => { }).catch((err) => {
Taro.showToast({
title: err.message,
icon: 'none'
});
})
}
const reload = async () => {
// 1.判断是否登录
if (!Taro.getStorageSync('UserId')) { if (!Taro.getStorageSync('UserId')) {
Taro.showToast({ Taro.showToast({
title: '请先登录', title: '请先登录',
icon: 'error' icon: 'error'
}) })
setDisabled(true);
setTimeout(() => {
Taro.navigateBack()
}, 2000)
return false return false
} }
const code = params.id;
// 获取数据字典
pageDictData({dictCode: 'InsuranceStatus'}).then(res => {
setDict(res?.list || [])
})
// 查询角色
listUserRole({userId: Taro.getStorageSync('UserId')}).then(res => {
if(res.length > 0){
setUserRole(res[0])
}
})
// 检查是否已实名
myUserVerify({status: 1}).then(data => {
if (!data) {
Taro.showToast({
title: '未实名认证',
icon: 'error'
})
setTimeout(() => {
Taro.navigateTo({
url: '/user/userVerify/index'
})
}, 1000)
return false
}
if(data){
setAdminId(data.userId);
setFormData( {...FormData, driverName: Taro.getStorageSync('RealName')})
}
})
// 获取车辆信息
if (code) {
getHjmCarByCode(code).then(data => {
if(data){
setFormData(data)
setKeywords(data.code)
// 解析图片数据 // 2.获取数据字典
if (data.image) { const dict = await pageDictData({dictCode: 'InsuranceStatus'})
try { setDict(dict?.list || [])
const parsedImages: UploadedImageData[] = JSON.parse(data.image)
setFileList(parsedImages.map((img) => ({ // 3.检查是否已实名
url: img.url, const verify = await myUserVerify({status: 1})
src: img.url if (!verify) {
}))) Taro.showToast({
} catch (error) { title: '未实名认证',
// 如果解析失败可能是旧格式的单个URL icon: 'error'
if (typeof data.image === 'string' && data.image.trim()) { })
setFileList([{ setTimeout(() => {
src: data.image, Taro.navigateTo({
url: data.image, url: '/user/userVerify/index'
message: '上传成功', })
type: 'image', }, 1000)
uid: `legacy_${Date.now()}`, return false
}]) }
}
// 4.查询角色
const role = await listUserRole({userId: Taro.getStorageSync('UserId')})
const roleCode = role[0].roleCode;
// 5.获取车辆信息
const code = params.id;
if (code) {
const carInfo = await getHjmCarByCode(code);
if (carInfo) {
// 赋值车辆信息
setFormData(carInfo)
setKeywords(carInfo.code)
if (carInfo.image) {
try {
const parsedImages: UploadedImageData[] = JSON.parse(carInfo.image)
setFileList(parsedImages.map((img) => ({
url: img.url,
src: img.url
})))
} catch (error) {
// 如果解析失败可能是旧格式的单个URL
if (carInfo.image && carInfo.image.trim()) {
setFileList([{
src: carInfo.image,
url: carInfo.image,
message: '上传成功',
type: 'image',
uid: `legacy_${Date.now()}`,
}])
} }
} }
}
if (data.status == 0) { // 1.符合条件则由安装人员安装车辆,否则提示无权限
console.log(roleCode,'roleCode..')
if (carInfo.status == 0 && roleCode != 'Installer') {
Taro.setNavigationBarTitle({
title: '安装设备'
})
Taro.showToast({
title: '您不是安装人员',
icon: 'error'
})
setDisabled(true)
return false
}
// 2.如果已安装,则判断是否已认领车辆
if (carInfo.status == 1 && roleCode == 'kuaidiyuan') {
// 2.1先查询名下有多少辆车
const carCount = await pageHjmCar({driverId: Taro.getStorageSync('UserId')})
if (carCount?.count && carCount?.count == 0) {
// 2.2无车辆则认领
setClaimVehicle(true)
Taro.setNavigationBarTitle({ Taro.setNavigationBarTitle({
title: '安装设备' title: '认领车辆'
}) })
setFormData({...data}) } else {
} // 2.3存在车辆则展示车辆信息
setClaimVehicle(false)
// 查询名下的车辆数 Taro.setNavigationBarTitle({
if(data?.status == 0 && Taro.getStorageSync('OrganizationParentId') != 0){ title: '车辆信息'
pageHjmCar({driverId: Taro.getStorageSync('UserId')}).then(res => {
if(res?.count && res?.count > 0){
setDisabled(true)
Taro.showToast({
title: '可绑定数量已达上限',
icon: 'none'
})
return false;
}
}) })
} }
} }
}) }
} }
// 执行搜索 // 执行搜索
if (keywords) { if (keywords) {
pageHjmCar({keywords}).then(res => { pageHjmCar({keywords}).then(res => {
@@ -434,10 +443,11 @@ const Query = () => {
} }
useEffect(() => { useEffect(() => {
reload() reload().then(() => {
console.log('初始化完成')
})
}, []) }, [])
return ( return (
<> <>
{/* 未安装 */} {/* 未安装 */}
@@ -525,6 +535,7 @@ const Query = () => {
<Input <Input
placeholder="请填入GPS设备编号" placeholder="请填入GPS设备编号"
value={FormData.gpsNo} value={FormData.gpsNo}
disabled={disabled}
onChange={(value) => setFormData({...FormData, gpsNo: value})} onChange={(value) => setFormData({...FormData, gpsNo: value})}
/> />
<div <div
@@ -629,7 +640,7 @@ const Query = () => {
<Form.Item <Form.Item
label={'操作员'} label={'操作员'}
name="driverName" name="driver"
rules={[{message: '操作员'}]} rules={[{message: '操作员'}]}
> >
<Input placeholder="操作员" type="text"/> <Input placeholder="操作员" type="text"/>
@@ -640,7 +651,7 @@ const Query = () => {
) : ''} ) : ''}
{/* 已安装 */} {/* 已安装 */}
{FormData?.status == 1 ? ( {FormData?.status != 0 ? (
<div className={'car-info w-full bg-white'}> <div className={'car-info w-full bg-white'}>
{/* 显示多张图片 */} {/* 显示多张图片 */}
<div style={{ <div style={{
@@ -685,9 +696,6 @@ const Query = () => {
<Cell className={'car-info-item-title'}> <Cell className={'car-info-item-title'}>
{FormData?.parentOrganizationAdmin} {FormData?.parentOrganizationAdmin}
</Cell> </Cell>
<Cell className={'car-info-item-content'}>
{FormData?.driver}
</Cell>
<Cell className={'car-info-item-content'}> <Cell className={'car-info-item-content'}>
{FormData?.insuranceStatus} {FormData?.insuranceStatus}
</Cell> </Cell>
@@ -697,35 +705,53 @@ const Query = () => {
<Cell className={'car-info-item-content'}> <Cell className={'car-info-item-content'}>
{FormData.fenceName} {FormData.fenceName}
</Cell> </Cell>
<div className={'flex justify-around py-4'}> <Cell className={'car-info-item-content'}>
<Button nativeType="submit" type="info" onClick={ {FormData.status == 2 ? FormData.driver : '-'}
() => { </Cell>
Taro.navigateTo({ {
url: `/hjm/location?id=${FormData?.code}` // 认领车辆
}) claimVehicle && (
} <div className={'flex justify-around py-4'}>
}> <Button nativeType="submit" type="danger" onClick={onClaimVehicle}>
</Button> </Button>
<Button nativeType="submit" type="warning" onClick={ </div>
() => { )
Taro.navigateTo({ }
url: `/hjm/trajectory/trajectory?id=${FormData?.code}` {
}) // 展示车辆信息
} !claimVehicle && !disabled && (
}> <div className={'flex justify-around py-4'}>
<Button nativeType="submit" type="info" onClick={
</Button> () => {
<Button nativeType="submit" type="default" onClick={ Taro.navigateTo({
() => { url: `/hjm/location?id=${FormData?.code}`
Taro.navigateTo({ })
url: `/hjm/gps-log/gps-log?id=${FormData?.gpsNo}` }
}) }>
}
}> </Button>
<Button nativeType="submit" type="warning" onClick={
</Button> () => {
</div> Taro.navigateTo({
url: `/hjm/trajectory/trajectory?id=${FormData?.code}`
})
}
}>
</Button>
<Button nativeType="submit" type="default" onClick={
() => {
Taro.navigateTo({
url: `/hjm/gps-log/gps-log?id=${FormData?.gpsNo}`
})
}
}>
</Button>
</div>
)
}
</div> </div>
</div> </div>
) : ''} ) : ''}

View File

@@ -43,6 +43,14 @@ const Header = (props: any) => {
if(data.certification){ if(data.certification){
Taro.setStorageSync('Certification','1') Taro.setStorageSync('Certification','1')
} }
// 安装人员
const isInstaller = data.roles?.findIndex(item => item.roleCode == 'Installer')
if(isInstaller != -1){
setRoleName('安装人员')
Taro.setStorageSync('RoleName', '安装人员')
Taro.setStorageSync('RoleCode', 'Installer')
return false;
}
// 管理员 // 管理员
const isKdy = data.roles?.findIndex(item => item.roleCode == 'admin') const isKdy = data.roles?.findIndex(item => item.roleCode == 'admin')
if(isKdy != -1){ if(isKdy != -1){

View File

@@ -5,7 +5,7 @@ import {pageCmsArticle} from "@/api/cms/cmsArticle";
import {CmsArticle} from "@/api/cms/cmsArticle/model"; import {CmsArticle} from "@/api/cms/cmsArticle/model";
import {checkMonthTaskCompleted} from "@/api/hjm/hjmExamLog"; import {checkMonthTaskCompleted} from "@/api/hjm/hjmExamLog";
import Questions from '@/components/Questions'; import Questions from '@/components/Questions';
import {getUserInfo} from "@/api/layout"; import {getWebsiteField} from "@/api/system/website/field";
/** /**
* 文章终极列表 * 文章终极列表
@@ -17,28 +17,28 @@ const Study = () => {
const [list, setList] = useState<CmsArticle[]>() const [list, setList] = useState<CmsArticle[]>()
const [monthTaskCompleted, setMonthTaskCompleted] = useState<boolean>(false) const [monthTaskCompleted, setMonthTaskCompleted] = useState<boolean>(false)
const reload = () => { const reload = async () => {
setLoading(true) setLoading(true)
getUserInfo().then((data) => { const field = await getWebsiteField(15524);
console.log(data) if (field.value == '0') {
if(data.certification){ setIsAdmin(true)
setIsAdmin(true) }else {
} setIsAdmin(false)
}) }
checkMonthTaskCompleted().then(res => { const article = await pageCmsArticle({categoryId: 4289, status: 0})
if (res) { if(article){
setMonthTaskCompleted(true) setList(article?.list)
} }
pageCmsArticle({categoryId: 4289, status: 0}).then(data => { const promise = await checkMonthTaskCompleted();
setList(data?.list) if(promise){
}) setMonthTaskCompleted(true)
}).finally(() => { }
setLoading(false)
})
} }
useEffect(() => { useEffect(() => {
reload() reload().then(() => {
console.log('初始化完成')
})
}, []) }, [])
return ( return (