增加知识科普tab页,将tab页之外的页面移到page-sub中,移除husky
parent
37300e3745
commit
be218b70f5
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* @Author: chris
|
||||
* @Date: 2025-11-10 10:21:14
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2025-11-17 10:26:02
|
||||
*/
|
||||
import { http } from '@/http/http'
|
||||
|
||||
export interface IDeviceDataQuery {
|
||||
deptId: string
|
||||
page: number
|
||||
pageSize: number
|
||||
type: number
|
||||
deviceId: string
|
||||
beginTime: string
|
||||
endTime: string
|
||||
}
|
||||
|
||||
export interface IDeviceDataItem {
|
||||
id: string
|
||||
deptId: string
|
||||
deviceNo: string
|
||||
model: string
|
||||
type: number
|
||||
data: string
|
||||
createTime: string
|
||||
}
|
||||
|
||||
// 查询设备数据列表
|
||||
export async function listDeviceData(query: IDeviceDataQuery) {
|
||||
return await http.get<IDeviceDataItem>('/business/device-data/list', query)
|
||||
}
|
||||
|
||||
// 导出设备数据
|
||||
export function exportDeviceData(query) {
|
||||
return http.post('/business/device-data/export', query, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
// 查询设备数据统计分析数据
|
||||
export function getDeviceDataAnalysis(params) {
|
||||
return http.get('/business/device-data/analysis', params)
|
||||
}
|
||||
|
||||
// export function listDeviceData(query) {
|
||||
// return request({
|
||||
// url: "/business/device-data/list",
|
||||
// method: "get",
|
||||
// params: query,
|
||||
// });
|
||||
// }
|
||||
|
||||
// 查询设备数据详细
|
||||
// export function getDeviceData(id) {
|
||||
// return request({
|
||||
// url: "/business/device-data/" + id,
|
||||
// method: "get",
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 查询设备数据统计分析数据
|
||||
// export function getDeviceDataAnalysis(params) {
|
||||
// return request({
|
||||
// url: "/business/device-data/analysis",
|
||||
// method: "get",
|
||||
// params,
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 新增设备数据
|
||||
// export function addDeviceData(data) {
|
||||
// return request({
|
||||
// url: "/business/device-data",
|
||||
// method: "post",
|
||||
// data,
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 修改设备数据
|
||||
// export function updateDeviceData(data) {
|
||||
// return request({
|
||||
// url: "/business/device-data",
|
||||
// method: "put",
|
||||
// data,
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 删除设备数据
|
||||
// export function delDeviceData(id) {
|
||||
// return request({
|
||||
// url: "/business/device-data/" + id,
|
||||
// method: "delete",
|
||||
// });
|
||||
// }
|
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* @Author: chris
|
||||
* @Date: 2026-01-19 16:49:53
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 16:59:22
|
||||
*/
|
||||
import { http } from '@/http/http'
|
||||
|
||||
export interface IKnowledgeListQuery {
|
||||
deptId: number
|
||||
content?: string
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
export interface IKnowledge {
|
||||
id: number
|
||||
title: string
|
||||
content: string
|
||||
createTime: string
|
||||
updateTime: string
|
||||
}
|
||||
|
||||
// 获取知识列表
|
||||
export async function getKnowledgeList(query: IKnowledgeListQuery) {
|
||||
return await http.get<IKnowledge[]>('/business/article/list', query)
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* @Author: chris
|
||||
* @Date: 2026-01-19 15:55:45
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 16:30:25
|
||||
*/
|
||||
import { http } from '@/http/http'
|
||||
|
||||
export interface IOrchardInfo {
|
||||
deptId: number
|
||||
deptName: string
|
||||
email: string
|
||||
leader: string
|
||||
parentId: number
|
||||
parentName: string
|
||||
phone: string
|
||||
plantingArea: string
|
||||
plantingNum: string
|
||||
remark: string
|
||||
status: string
|
||||
terrain: string
|
||||
updateBy: string
|
||||
updateTime: string
|
||||
variety: string
|
||||
}
|
||||
|
||||
// 获取果园信息
|
||||
export async function getOrchardInfo(orchardId: string) {
|
||||
return await http.get<IOrchardInfo>(`/system/dept/${orchardId}`)
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
import { http } from '@/http/http'
|
||||
|
||||
export interface IWarningQuery {
|
||||
deptId: number
|
||||
beginTime?: string
|
||||
endTime?: string
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
export interface IWarning {
|
||||
id: number
|
||||
deptId: number
|
||||
notifyContent: string
|
||||
createTime: string
|
||||
}
|
||||
|
||||
// 获取预警列表
|
||||
export async function getWarningList(query: IWarningQuery) {
|
||||
return await http.get<IWarning[]>(`/business/notify-log/list`, query)
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* @Author: chris
|
||||
* @Date: 2025-11-10 10:21:14
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 15:43:07
|
||||
*/
|
||||
import { http } from '@/http/http'
|
||||
|
||||
export interface IResetPassword {
|
||||
userId: string
|
||||
password: string
|
||||
}
|
||||
|
||||
// 重置用户密码
|
||||
export async function resetPassword(query: IResetPassword) {
|
||||
return await http.put<IResetPassword>('/system/user/resetPwd', query)
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
<!--
|
||||
* @Author: chris
|
||||
* @Date: 2026-01-06 17:17:48
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 15:52:08
|
||||
-->
|
||||
<template>
|
||||
<view class="changePassword-page">
|
||||
<wd-form ref="form" :model="model">
|
||||
<wd-cell-group border>
|
||||
<!-- <wd-input
|
||||
v-model="form.oldPwd"
|
||||
label="旧密码"
|
||||
label-width="100px"
|
||||
prop="oldPwd"
|
||||
show-password
|
||||
clearable
|
||||
placeholder="请输入旧密码"
|
||||
:rules="[{ required: true, message: '请填写密码' }]"
|
||||
/> -->
|
||||
<wd-input
|
||||
v-model="form.newPwd"
|
||||
label="新密码"
|
||||
label-width="100px"
|
||||
prop="newPwd"
|
||||
show-password
|
||||
clearable
|
||||
placeholder="请输入新密码"
|
||||
:rules="[{ required: true, message: '请填写密码' }]"
|
||||
/>
|
||||
</wd-cell-group>
|
||||
<view class="footer">
|
||||
<wd-button type="primary" size="large" block @click="handleSubmit">
|
||||
提交
|
||||
</wd-button>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { resetPassword } from '@/api/user'
|
||||
|
||||
const form = ref({
|
||||
// oldPwd: '',
|
||||
newPwd: '',
|
||||
})
|
||||
|
||||
function handleSubmit() {
|
||||
// form.value.oldPwd = form.value.oldPwd.trim()
|
||||
resetPassword({
|
||||
userId: uni.getStorageSync('userId'),
|
||||
password: form.value.newPwd,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
uni.showToast({
|
||||
title: '密码重置成功',
|
||||
icon: 'success',
|
||||
})
|
||||
uni.navigateBack()
|
||||
}
|
||||
form.value.newPwd = form.value.newPwd.trim()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.changePassword-page {
|
||||
padding: 20rpx;
|
||||
|
||||
.footer {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,37 @@
|
||||
<!--
|
||||
* @Author: chris
|
||||
* @Date: 2026-01-06 17:43:28
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 15:30:16
|
||||
-->
|
||||
<script setup>
|
||||
const content = ref('')
|
||||
|
||||
function submitFeedback() {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="feedback-container">
|
||||
<wd-form ref="form" :model="model">
|
||||
<wd-textarea v-model="content" placeholder="请填写反馈内容" />
|
||||
<view class="footer">
|
||||
<wd-button type="primary" size="large" block @click="submitFeedback">
|
||||
提交反馈
|
||||
</wd-button>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.feedback-container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
height: 100vh;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,60 @@
|
||||
<!--
|
||||
* @Author: chris
|
||||
* @Date: 2026-01-19 17:59:19
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 18:18:52
|
||||
-->
|
||||
<script setup>
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '预警推送设置',
|
||||
},
|
||||
})
|
||||
|
||||
const pushPlatform = ref('')
|
||||
const pushTemplate = ref('')
|
||||
|
||||
const platformTypes = [
|
||||
{
|
||||
label: '公众号',
|
||||
value: 'wechat',
|
||||
},
|
||||
{
|
||||
label: '短信',
|
||||
value: 'sms',
|
||||
},
|
||||
]
|
||||
|
||||
const templateTypes = [
|
||||
{
|
||||
label: '模板1',
|
||||
value: 'template1',
|
||||
},
|
||||
{
|
||||
label: '模板2',
|
||||
value: 'template2',
|
||||
},
|
||||
]
|
||||
|
||||
function handleChange(item, type) {
|
||||
if (type === 'platform') {
|
||||
pushPlatform.value = item.value
|
||||
}
|
||||
else if (type === 'template') {
|
||||
pushTemplate.value = item.value
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="warning-setting">
|
||||
<wd-select-picker v-model="pushPlatform" value-key="value" label-key="label" label="推送平台" type="radio" :columns="platformTypes" @change="handleChange($event, 'platform')" />
|
||||
<wd-select-picker v-model="pushTemplate" value-key="value" label-key="label" label="推送模板" type="radio" :columns="templateTypes" @change="handleChange($event, 'template')" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.warning-setting {
|
||||
@apply bg-[#f8f8f8] h-[100vh] py-[20rpx];
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,239 @@
|
||||
<!--
|
||||
* @Author: chris
|
||||
* @Date: 2025-12-02 09:43:34
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 17:07:21
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import type { IKnowledge, IKnowledgeListQuery } from '@/api/knowledge'
|
||||
import { getKnowledgeList } from '@/api/knowledge'
|
||||
|
||||
// 状态管理
|
||||
const searchQuery = ref<string>('')
|
||||
const queryParams = ref<IKnowledgeListQuery>({
|
||||
deptId: 0,
|
||||
content: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
const pestList = ref<IKnowledge[]>([])
|
||||
const isLoading = ref(false)
|
||||
|
||||
// 加载数据
|
||||
async function loadData() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const res = await getKnowledgeList(queryParams.value)
|
||||
pestList.value = res || []
|
||||
}
|
||||
finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理搜索
|
||||
function handleSearch() {
|
||||
queryParams.value.content = searchQuery.value
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 跳转到详情页
|
||||
function navigateToDetail(id: number) {
|
||||
uni.navigateTo({
|
||||
url: '/pages-sub/pest/detail',
|
||||
query: { id },
|
||||
})
|
||||
}
|
||||
|
||||
// 页面加载时获取数据
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<scroll-view scroll-y class="pest-knowledge-page">
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-container">
|
||||
<view class="search-box">
|
||||
<uni-icons name="search" size="20" color="#999" class="search-icon" />
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
placeholder="搜索虫害知识..."
|
||||
class="search-input"
|
||||
@input="handleSearch"
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 知识列表 -->
|
||||
<view class="knowledge-list">
|
||||
<uni-load-more
|
||||
v-if="isLoading"
|
||||
status="loading"
|
||||
class="loading-indicator"
|
||||
/>
|
||||
|
||||
<!-- 列表为空提示 -->
|
||||
<view v-else-if="pestList.length === 0" class="empty-state">
|
||||
<uni-icons name="warning-empty" size="60" color="#ccc" />
|
||||
<text class="empty-text">暂无相关知识</text>
|
||||
</view>
|
||||
|
||||
<!-- 列表项 -->
|
||||
<view
|
||||
v-for="item in pestList"
|
||||
v-else
|
||||
:key="item.id"
|
||||
class="knowledge-item"
|
||||
@click="navigateToDetail(item.id)"
|
||||
>
|
||||
<view class="item-image">
|
||||
<image :src="item.imageUrl" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="item-content">
|
||||
<text class="item-title">{{ item.title }}</text>
|
||||
<text class="item-description">{{ item.content }}</text>
|
||||
<view class="item-meta">
|
||||
<text class="item-date">{{ item.createTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pest-knowledge-page {
|
||||
height: calc(100vh - 50px - var(--safe-area-inset-bottom));
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
/* 搜索框 */
|
||||
.search-container {
|
||||
padding: 12px 20px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 20px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 知识列表 */
|
||||
.knowledge-list {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.loading-indicator {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 0;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin-top: 12px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 列表项 */
|
||||
.knowledge-item {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
transition:
|
||||
transform 0.2s,
|
||||
box-shadow 0.2s;
|
||||
|
||||
+ .knowledge-item {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.knowledge-item:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.item-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-right: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.item-image image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item-description {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin-bottom: 12px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.item-date {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* @Author: chris
|
||||
* @Date: 2026-01-19 17:35:18
|
||||
* @LastEditors: chris
|
||||
* @LastEditTime: 2026-01-19 17:38:51
|
||||
*/
|
||||
export function formatDate(cellValue: string | number): string {
|
||||
if (cellValue == null || cellValue === '')
|
||||
return ''
|
||||
const date = new Date(cellValue)
|
||||
const year = date.getFullYear()
|
||||
const month
|
||||
= date.getMonth() + 1 < 10
|
||||
? `0${date.getMonth() + 1}`
|
||||
: date.getMonth() + 1
|
||||
const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()
|
||||
const hours = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
|
||||
const minutes
|
||||
= date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
|
||||
const seconds
|
||||
= date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
|
||||
return (
|
||||
`${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue