提交 fb92718d 作者: 宇宙超人

设备模块

上级 a5aa2470
...@@ -10,6 +10,50 @@ enum Api { ...@@ -10,6 +10,50 @@ enum Api {
getFarmBaseList = '/farmbase/getFarmBaseList', getFarmBaseList = '/farmbase/getFarmBaseList',
} }
/** /**
* 删除设备
* @param id
* @returns
*/
export function delDevice(id) {
return otherHttp.post({
url: '/device/delete?id='+id,
})
}
/**
* 编辑设备
* @param params
* @returns
*/
export function editDevice(params = {}) {
return otherHttp.post({
url: '/device/edit',
params,
})
}
/**
* 添加设备
* @param params
* @returns
*/
export function addDevice(params = {}) {
return otherHttp.post({
url: '/device/add',
params,
})
}
/**
* 设备列表
* @param params
* @returns
*/
export function getDeviceList(params: any = {}) {
return otherHttp.get({
url: '/device/list',
params,
})
}
/**
* 农场基地管理-通过id查询 * 农场基地管理-通过id查询
* @param params * @param params
* @returns * @returns
...@@ -27,7 +71,7 @@ export function getFarmbaseInfoById(params: any = {}) { ...@@ -27,7 +71,7 @@ export function getFarmbaseInfoById(params: any = {}) {
*/ */
export function delFarmbase(id) { export function delFarmbase(id) {
return otherHttp.delete({ return otherHttp.delete({
url: '/farmbase/delete?id='+id, url: '/farmbase/delete?id=' + id,
}) })
} }
/** /**
......
{ {
"name" : "数字农服", "name" : "数字农服",
"appid" : "__UNI__FD09823", "appid" : "__UNI__A9A0BAC",
"description" : "数字农服 APP", "description" : "数字农服 APP",
"versionName" : "1.0.9", "versionName" : "1.0.9",
"versionCode" : 10009, "versionCode" : 10009,
......
...@@ -276,7 +276,8 @@ ...@@ -276,7 +276,8 @@
"text": "+ 添加基地", "text": "+ 添加基地",
"fontSrc": "/static/uni.ttf", "fontSrc": "/static/uni.ttf",
"color": "#fff", "color": "#fff",
"fontSize": "28rpx" "fontSize": "28rpx",
"width":"auto"
} }
] ]
} }
...@@ -364,6 +365,30 @@ ...@@ -364,6 +365,30 @@
"style": { "style": {
"navigationBarTitleText": "添加基地" "navigationBarTitleText": "添加基地"
} }
},
{
"path": "pages/device/device",
"style": {
"navigationBarTitleText": "物联设备",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#5DB66F",
"navigationBarTextStyle": "white",
"backgroundColorBottom": "#F2F2F2",
"app-plus": {
"titleNView": {
"titleSize": "20",
"buttons": [
{
"text": "+ 添加设备",
"fontSrc": "/static/uni.ttf",
"color": "#fff",
"fontSize": "28rpx",
"width":"auto"
}
]
}
}
}
} }
], ],
"easycom": { "easycom": {
......
<template>
<u-modal :show="show" :title="dialogTitle" :showConfirmButton="false" :showCancelButton="false"
@close="handleClose" :closeOnClickOverlay="false">
<view class="dialog-content">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="180rpx">
<!-- 设备基本信息 -->
<view class="section-title">设备基本信息</view>
<u-form-item label="设备名称" prop="deviceName" required>
<u-input v-model="formData.deviceName" placeholder="请输入设备名称" border="bottom" />
</u-form-item>
<u-form-item label="设备类型" prop="deviceType" required>
<u-input v-model="formData.deviceTypeText" placeholder="请选择设备类型" border="bottom"
@click="showDeviceTypePicker = true" />
</u-form-item>
<u-form-item label="设备标识" prop="deviceIdentifier" required>
<u-input v-model="formData.deviceIdentifier" placeholder="序列号/MAC地址等" border="bottom" />
</u-form-item>
<!-- 操作按钮 -->
<view class="dialog-buttons">
<u-button type="primary" @click="handleSubmit" :loading="loading" size="normal" class="submit-btn" color="var(--fui-color-success)">
{{ submitButtonText }}
</u-button>
<u-button @click="handleClose" size="normal" class="cancel-btn">取消</u-button>
</view>
</u-form>
<!-- 设备类型选择器 -->
<fui-picker :show="showDeviceTypePicker" :options="deviceTypeOptions" :layer="1" :linkage="true"
@change="handleDeviceTypeConfirm" @cancel="showDeviceTypePicker = false"></fui-picker>
</view>
</u-modal>
</template>
<script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue'
import { useDictStore } from '@/store/modules/dict'
import * as NongchangAPI from '@/api/model/nongchang'
// 定义Props
interface Props {
show: boolean
editData?: any
}
const props = withDefaults(defineProps<Props>(), {
show: false,
editData: null
})
// 定义Emits
const emit = defineEmits<{
'update:show': [value: boolean]
'submit': [data: any]
'close': []
}>()
// 表单引用
const formRef = ref()
const loading = ref(false)
const showDeviceTypePicker = ref(false)
// 字典存储
const dictStore = useDictStore()
// 表单数据
const formData = reactive({
deviceName: '',
deviceType: '',
deviceTypeText: '',
deviceIdentifier: ''
})
// 设备类型选项 - 使用字典数据
const deviceTypeOptions = computed(() => {
return dictStore.getDictList['deviceType']?.map((item: any) => ({
value: item.value,
text: item.text
})) || []
})
// 设备类型选择器数据 (不再需要,因为fui-picker使用options属性)
// 计算属性
const dialogTitle = computed(() => {
return props.editData ? '编辑设备' : '添加设备'
})
const submitButtonText = computed(() => {
return props.editData ? '保存' : '确认'
})
// 表单验证规则
const rules = {
deviceName: [
{ required: true, message: '请输入设备名称', trigger: 'blur' },
{ min: 2, max: 50, message: '设备名称长度在2-50个字符之间', trigger: 'blur' }
],
deviceType: [
{ required: true, message: '请选择设备类型',type:'number', trigger: 'change' }
],
deviceIdentifier: [
{ required: true, message: '请输入设备唯一标识', trigger: 'blur' },
{ min: 6, max: 100, message: '设备标识长度在6-100个字符之间', trigger: 'blur' },
{
validator: (rule: any, value: any, callback: any) => {
if (!/^[a-zA-Z0-9\-_:]+$/.test(value)) {
callback(new Error('设备标识只能包含字母、数字、下划线、中划线和冒号'))
} else {
callback()
}
},
trigger: 'blur'
}
]
}
// 监听显示状态
watch(() => props.show, (newVal) => {
if (newVal && props.editData) {
// 编辑模式,填充数据
resetFormData()
loadEditData()
} else if (newVal) {
// 添加模式,重置表单
resetFormData()
}
})
// 重置表单数据
const resetFormData = () => {
formData.deviceName = ''
formData.deviceType = ''
formData.deviceTypeText = ''
formData.deviceIdentifier = ''
// 清除验证状态
if (formRef.value) {
formRef.value.resetFields()
}
}
// 加载编辑数据
const loadEditData = () => {
if (!props.editData) return
formData.deviceName = props.editData.deviceName || ''
formData.deviceType = props.editData.deviceType || ''
formData.deviceIdentifier = props.editData.deviceIdentifier || ''
// 设置设备类型文本
if (props.editData.deviceType) {
const typeOption = deviceTypeOptions.value.find(item => item.value === props.editData.deviceType)
if (typeOption) {
formData.deviceTypeText = typeOption.text
} else {
// 如果字典中没有找到对应的文本,使用原始数据中的文本
formData.deviceTypeText = props.editData.deviceType_dictText || ''
}
} else {
formData.deviceTypeText = ''
}
}
// 设备类型选择确认
const handleDeviceTypeConfirm = (e: any) => {
formData.deviceType = e.value
formData.deviceTypeText = e.text
showDeviceTypePicker.value = false
}
// 提交表单
const handleSubmit = async () => {
try {
console.log(formData)
// 先进行表单验证
const valid = await formRef.value.validate()
if (!valid) {
return
}
loading.value = true
// 准备提交数据
const submitData = {
...formData
}
// 根据 editData 判断是新增还是修改
let result
if (props.editData && props.editData.id) {
// 编辑设备,需要传递设备ID
result = await NongchangAPI.editDevice({
...submitData,
id: props.editData.id
})
console.log('修改设备数据:', submitData)
} else {
// 新增设备
result = await NongchangAPI.addDevice(submitData)
console.log('新增设备数据:', submitData)
}
uni.showToast({ title: '操作成功', icon: 'success' })
emit('update:show', false)
emit('submitSuccess')
} catch (error) {
console.log('提交失败:', error)
uni.showToast({
title: '操作失败',
icon: 'none',
duration: 2000
})
} finally {
loading.value = false
}
}
// 关闭弹窗
const handleClose = () => {
emit('update:show', false)
emit('close')
}
// 暴露方法给父组件
defineExpose({
resetFormData,
setLoading: (value: boolean) => {
loading.value = value
}
})
</script>
<style lang="scss" scoped>
.dialog-content {
padding: 10rpx 30rpx;
width: 90%;
max-height: 80vh;
overflow-y: auto;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin: 20rpx 0 30rpx 0;
padding-left: 20rpx;
border-left: 6rpx solid #5DB66F;
}
.dialog-buttons {
display: flex;
gap: 20rpx;
margin-top: 40rpx;
.submit-btn {
flex: 1;
::v-deep .u-button {
background-color: #5DB66F;
border-color: #5DB66F;
}
}
.cancel-btn {
flex: 1;
::v-deep .u-button {
background-color: #fff;
color: #666;
border: 2rpx solid #dcdfe6;
}
}
}
// uview-plus 表单样式调整
::v-deep .u-form-item {
margin-bottom: 40rpx;
.u-form-item__body {
padding: 0;
align-items: flex-start;
}
.u-form-item__body__left__content__label {
font-size: 28rpx;
color: #333;
font-weight: 500;
width: 180rpx;
flex-shrink: 0;
text-align: right;
padding-right: 20rpx;
line-height: 80rpx;
}
.u-form-item__body__right {
flex: 1;
min-width: 0;
}
}
::v-deep .u-form-item__body__left__content__required {
position: static;
padding-right: 10rpx;
}
// 输入框样式优化
::v-deep .u-input {
.u-input__content {
padding: 0;
.u-input__content__field-wrapper {
border: none;
border-radius: 0;
.u-input__content__field-wrapper__field {
font-size: 28rpx;
height: auto;
}
.u-input__content__field-wrapper__placeholder {
color: #c0c4cc;
font-size: 28rpx;
}
}
&.u-input--focus {
.u-input__content__field-wrapper {
border-bottom-color: #5DB66F;
}
}
}
}
// 模态框样式调整
::v-deep .u-modal {
.u-modal__content {
border-radius: 20rpx;
padding: 20rpx 0rpx;
}
.u-modal__header {
border-bottom: 2rpx solid #f0f0f0;
padding: 30rpx;
.u-modal__header__title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
}
}
</style>
<template>
<view class="codefun-flex-col page">
<z-paging ref="paging" v-model="pageData.list" @query="queryList">
<view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input v-model="pageData.param.deviceName" placeholder="请输入设备名称搜索" border="none"
class="codefun-ml-8" @confirm="handleSearch" />
</view>
<!-- 设备列表 -->
<view class="device-list">
<uni-swipe-action>
<uni-swipe-action-item v-for="(item, index) in pageData.list" :key="index" :right-options="swipeOptions"
@click="(e) => handleSwipeAction(e, item)">
<view class="device-item">
<view class="device-info">
<view class="device-name">{{ item.deviceName }}</view>
<view class="device-details">
<text class="device-type">类型: {{ item.deviceType_dictText || '未知' }}</text>
<text class="device-identifier">标识: {{ item.deviceIdentifier }}</text>
</view>
</view>
<view class="device-status-time">
<text class="device-status" :class="getStatusClass(item.connectStatus)">
{{ item.connectStatus_dictText || '未知' }}
</text>
<view style="opacity: 0;">1</view>
<view class="device-time">添加日期: {{ item.createTime }}</view>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="pageData.list.length === 0">
<text>暂无设备数据</text>
</view>
</view>
</z-paging>
<!-- 弹窗组件 -->
<save-dialog :show="showDialog" :editData="currentEditData" @update:show="showDialog = $event"
@submitSuccess="handleSubmitSuccess" @close="handleDialogClose" />
</view>
</template>
<script setup>
import { nextTick, reactive, ref } from 'vue'
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app'
import * as NongchangAPI from '@/api/model/nongchang'
import SaveDialog from './components/save-dialog.vue'
const isOnePage = ref(true)
const paging = ref(null)
const pageData = reactive({
param: {
pageNo: 1,
pageSize: 10,
deviceName: '',
},
list: [],
})
// 滑动操作选项
const swipeOptions = [
{
text: '编辑',
style: {
backgroundColor: 'var(--fui-color-primary)'
}
},
{
text: '删除',
style: {
backgroundColor: 'var(--fui-color-danger)'
}
}
]
function getList() {
if (!paging.value) return
NongchangAPI.getDeviceList(pageData.param)
.then((res) => {
pageData.total = res.total
paging.value.complete(res.records)
})
.catch(() => {
paging.value.complete(false)
})
}
function queryList(pageNo, pageSize) {
pageData.param.pageNo = pageNo
pageData.param.pageSize = pageSize
getList()
}
function handleSearch() {
// 重置页码为1,重新搜索
pageData.param.pageNo = 1
if (paging.value) {
paging.value.reload()
}
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
})
const showAddDialog = () => {
currentEditData.value = null
showDialog.value = true
}
const showEditDialog = (device) => {
currentEditData.value = device
showDialog.value = true
}
const handleSubmitSuccess = () => {
// 提交成功后刷新列表
handleSearch()
}
const handleDialogClose = () => {
// 弹窗关闭后的处理逻辑
}
// 删除设备
const handleDelete = async (id) => {
try {
await uni.showModal({
title: '确认删除',
content: '确定要删除这个设备吗?',
success: async (res) => {
if (res.confirm) {
await NongchangAPI.delDevice( id )
uni.showToast({ title: '删除成功', icon: 'success' })
handleSearch()
}
}
})
} catch (error) {
uni.showToast({ title: '删除失败', icon: 'none' })
}
}
// 获取状态样式类
const getStatusClass = (status) => {
if (status === '已连接') return 'status-connected'
if (status === '未连接') return 'status-disconnected'
return 'status-unknown'
}
// 处理滑动打开事件
const handleSwipeOpen = (index) => {
// 关闭其他已打开的滑动单元格,确保同时只有一个处于打开状态
pageData.list.forEach((item, i) => {
item.isShow = i === index
})
}
// 处理滑动操作
const handleSwipeAction = (e, device) => {
const index = e.index
const position = e.position
if (position === 'right') {
if (index === 0) {
// 编辑操作
showEditDialog(device)
} else if (index === 1) {
// 删除操作
handleDelete(device.id)
}
}
}
</script>
<style lang="scss">
body {
background-color: #e6f5e8;
}
.mt-5 {
margin-top: 10rpx;
}
.mt-11 {
margin-top: 22rpx;
}
.ml-5 {
margin-left: 10rpx;
}
.ml-13 {
margin-left: 26rpx;
}
.ml-9 {
margin-left: 18rpx;
}
.page {
background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
.section {
padding: 32rpx 24rpx 32rpx 36rpx;
background-color: #5db66f;
mix-blend-mode: NOTTHROUGH;
.image {
border-radius: 64rpx;
width: 108rpx;
height: 42rpx;
}
.group {
margin-right: 4rpx;
.image_2 {
mix-blend-mode: NOTTHROUGH;
width: 34rpx;
height: 22rpx;
}
.image_3 {
mix-blend-mode: NOTTHROUGH;
width: 30rpx;
height: 22rpx;
}
.image_4 {
width: 48rpx;
height: 22rpx;
}
}
.group_2 {
padding-left: 6rpx;
.image_5 {
mix-blend-mode: NOTTHROUGH;
width: 14rpx;
height: 26rpx;
}
.pos {
position: absolute;
left: 6rpx;
top: 50%;
transform: translateY(-50%);
}
.text {
color: #ffffffe6;
line-height: 29.6rpx;
}
.pos_2 {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
.text_2 {
line-height: 25.78rpx;
}
}
}
}
.group_3 {
padding: 28rpx 24rpx 58rpx;
.section_2 {
padding: 16rpx 20rpx;
background-color: #ffffff;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
.text_3 {
color: #cccccc;
line-height: 26.02rpx;
}
}
.section_3 {
padding: 0 24rpx;
background-color: #ffffff;
border-radius: 18.46rpx;
mix-blend-mode: NOTTHROUGH;
.group_4 {
padding: 42rpx 4rpx 30rpx 22rpx;
border-bottom: solid 2rpx #eeeeee;
.image_7 {
width: 100rpx;
height: 86rpx;
}
.group_7 {
margin-left: 32rpx;
.text_5 {
color: #5db66f;
font-size: 40rpx;
font-family: SourceHanSansCN;
line-height: 40rpx;
}
.text_7 {
line-height: 22.18rpx;
}
}
.text_4 {
color: #333333;
line-height: 40rpx;
}
.group_5 {
width: 219.94rpx;
.group_6 {
overflow: hidden;
.text-wrapper_2 {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 60rpx;
height: 40rpx;
}
}
.group_8 {
padding-top: 16rpx;
.text-wrapper_3 {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 60rpx;
height: 40rpx;
.text_8 {
color: #ff9800;
}
}
}
.text-wrapper {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 112rpx;
height: 40rpx;
.text_6 {
line-height: 25.74rpx;
}
}
}
}
.group_9 {
padding: 12rpx 4rpx;
.image_8 {
margin: 4rpx 0;
width: 40rpx;
height: 40rpx;
}
.text-wrapper_4 {
padding: 12rpx 0;
overflow: hidden;
width: 168rpx;
height: 48rpx;
}
.image_9 {
margin-right: 12rpx;
width: 16rpx;
height: 26rpx;
}
}
.font_5 {
font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #5db66f;
}
}
.font_3 {
font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #1f2937;
}
.section_4 {
padding-left: 6rpx;
padding-bottom: 26rpx;
background-color: #ffffff;
border-radius: 26.28rpx;
mix-blend-mode: NOTTHROUGH;
.list {
margin-left: 18rpx;
margin-right: 24rpx;
.list-item {
padding: 24rpx 0;
border-bottom: solid 2rpx #eeeeee;
.section_5 {
padding: 12rpx 0 116rpx;
background-image: url('/static/images/codefun/4be80e2618f3c4b4aa1ce64fd9063abf.png');
background-size: 100% 100%;
background-repeat: no-repeat;
width: 160rpx;
height: 160rpx;
.text-wrapper_5 {
padding: 8rpx 0;
background-image: linear-gradient(90deg, #43cf7c 0%, #5db66f 100%);
border-radius: 0rpx 8rpx 8rpx 0rpx;
mix-blend-mode: NOTTHROUGH;
width: 84rpx;
.font_6 {
font-size: 20rpx;
font-family: SourceHanSansCN;
line-height: 18.38rpx;
color: #ffffff;
}
}
}
.group_10 {
margin-right: 40rpx;
.text_9 {
line-height: 22.34rpx;
}
.text_10 {
line-height: 22.22rpx;
}
.group_11 {
padding-left: 64rpx;
.image_10 {
width: 28rpx;
height: 28rpx;
}
.text-wrapper_6 {
padding-top: 8rpx;
overflow: hidden;
width: 48rpx;
height: 32rpx;
.text_11 {
line-height: 22.12rpx;
}
}
.font_8 {
font-size: 24rpx;
font-family: SourceHanSansCN;
line-height: 22.28rpx;
color: #f44336;
}
}
}
}
}
.group_14 {
margin: 18rpx 24rpx 0;
.text_14 {
line-height: 26.12rpx;
}
.text-wrapper_8 {
padding: 4rpx 0;
overflow: hidden;
width: 48rpx;
height: 32rpx;
.text_15 {
line-height: 22.2rpx;
}
}
}
.font_7 {
font-size: 24rpx;
font-family: SourceHanSansCN;
line-height: 22.28rpx;
color: #5db66f;
}
.group_15 {
margin-left: 24rpx;
margin-top: 28rpx;
width: 528.18rpx;
.text_16 {
line-height: 25.12rpx;
}
.text_17 {
line-height: 26.26rpx;
}
}
.group_16 {
margin-left: 24rpx;
margin-top: 28rpx;
width: 216.94rpx;
.text_18 {
line-height: 25.82rpx;
}
.text_19 {
line-height: 25.34rpx;
}
}
.font_9 {
font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #6b7280;
}
.group_17 {
margin-left: 24rpx;
margin-top: 28rpx;
.text_20 {
line-height: 26.16rpx;
}
.text_21 {
line-height: 22.66rpx;
}
}
.divider {
margin: 28rpx 18rpx 0 24rpx;
background-color: #f3f4f6;
height: 2rpx;
}
.text_22 {
margin-left: 24rpx;
margin-top: 32rpx;
line-height: 26.12rpx;
}
.group_18 {
margin-left: 24rpx;
margin-top: 32rpx;
.text_23 {
line-height: 26.06rpx;
}
.text_24 {
line-height: 22.66rpx;
}
}
.font_10 {
font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 22.28rpx;
color: #1f2937;
}
.group_19 {
margin-left: 24rpx;
margin-top: 28rpx;
.text_25 {
line-height: 25.9rpx;
}
.text_26 {
line-height: 25.78rpx;
}
}
.group_20 {
margin-left: 24rpx;
margin-top: 32rpx;
.text_27 {
line-height: 25.96rpx;
}
.text_28 {
line-height: 25.88rpx;
}
}
.divider_2 {
margin-top: 28rpx;
background-color: #f3f4f6;
width: 716rpx;
height: 2rpx;
}
.text-wrapper_9 {
margin-left: 24rpx;
margin-top: 32rpx;
padding: 24rpx 0;
background-color: #5db66f;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
.text_29 {
line-height: 25.9rpx;
}
}
}
.font_4 {
font-size: 24rpx;
font-family: SourceHanSansCN;
line-height: 22.28rpx;
color: #555555;
}
}
.image_6 {
width: 32rpx;
height: 32rpx;
}
.font {
font-size: 32rpx;
font-family: SourceHanSansCN;
line-height: 29.88rpx;
color: #333333;
}
.font_2 {
font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #ffffff;
}
}
/* 设备列表样式 */
.device-list {
margin-top: 20rpx;
}
.device-item {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
display: flex;
// justify-content: space-between;
align-items: center;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
::v-deep .uni-swipe_box {
border-radius: 16rpx;
margin-bottom: 20rpx;
}
.device-info {
flex: 1;
}
.device-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 8rpx;
border-left: 6rpx solid #5DB66F;
padding-left: 6rpx;
}
.device-details {
display: flex;
flex-direction: column;
gap: 6rpx;
margin-bottom: 8rpx;
}
.device-type,
.device-identifier {
font-size: 24rpx;
color: #666666;
}
.device-status-time {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6rpx;
min-width: 180rpx;
}
.device-status {
font-size: 24rpx;
font-weight: bold;
}
.device-time {
font-size: 22rpx;
color: #999999;
}
.device-actions {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.status-connected {
color: #5db66f !important;
font-weight: bold;
}
.status-disconnected {
color: #f44336 !important;
font-weight: bold;
}
.status-unknown {
color: #ff9800 !important;
font-weight: bold;
}
.empty-state {
text-align: center;
padding: 100rpx 0;
color: #999999;
font-size: 28rpx;
}
</style>
<script setup lang="ts"> <script setup lang="ts">
import { nextTick, reactive, ref } from 'vue' import { nextTick, reactive, ref } from 'vue'
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app' import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app'
import * as NongchangAPI from '@/api/model/nongchang' import * as NongchangAPI from '@/api/model/nongchang'
const isOnePage = ref(true) const isOnePage = ref(true)
const paging = ref(null) const paging = ref(null)
const pageData = reactive({ const pageData = reactive({
param: { param: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
total: 0, // 基地总数 total: 0, // 基地总数
type_success_total: 0, // 已认证 type_success_total: 0, // 已认证
type_unverified_total: 0, // 未认证 type_unverified_total: 0, // 未认证
}) })
onNavigationBarButtonTap((e) => { onNavigationBarButtonTap((e) => {
console.log('onNavigationBarButtonTap', e) console.log('onNavigationBarButtonTap', e)
}) })
onLoad(() => {}) onLoad(() => { })
onShow(() => { onShow(() => {
nextTick(() => { nextTick(() => {
if (!isOnePage.value && paging.value) { if (!isOnePage.value && paging.value) {
paging.value.reload() paging.value.reload()
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
isOnePage.value = false isOnePage.value = false
}) })
}) })
function getList() { function getList() {
if (!paging.value) return if (!paging.value) return
NongchangAPI.getFarmbaseList(pageData.param) NongchangAPI.getFarmbaseList(pageData.param)
...@@ -40,30 +40,30 @@ function getList() { ...@@ -40,30 +40,30 @@ function getList() {
paging.value.complete(false) paging.value.complete(false)
}) })
} }
onNavigationBarButtonTap((_) => { onNavigationBarButtonTap((_) => {
uni.navigateTo({ uni.navigateTo({
url: './add', url: './add',
}) })
}) })
function queryList(pageNo, pageSize) { function queryList(pageNo, pageSize) {
pageData.param.pageNo = pageNo pageData.param.pageNo = pageNo
pageData.param.pageSize = pageSize pageData.param.pageSize = pageSize
getList() getList()
} }
function handleSearch() { function handleSearch() {
// 重置页码为1,重新搜索 // 重置页码为1,重新搜索
pageData.param.pageNo = 1 pageData.param.pageNo = 1
if (paging.value) { if (paging.value) {
paging.value.reload() paging.value.reload()
} }
} }
const goDetail = (id)=>{ const goDetail = (id) => {
uni.navigateTo({ uni.navigateTo({
url: './add?id='+id, url: './add?id=' + id,
}) })
} }
function del(id) { function del(id) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定删除吗?', content: '确定删除吗?',
...@@ -81,7 +81,7 @@ function getList() { ...@@ -81,7 +81,7 @@ function getList() {
} }
}, },
}) })
} }
</script> </script>
<template> <template>
...@@ -90,24 +90,16 @@ function getList() { ...@@ -90,24 +90,16 @@ function getList() {
<view class="codefun-flex-col group_3"> <view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2"> <view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" /> <image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input <u-input v-model="pageData.param.baseName" placeholder="请输入搜索内容" border="none" class="codefun-ml-8"
v-model="pageData.param.baseName" @confirm="handleSearch" />
placeholder="请输入搜索内容"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view> </view>
<view class="codefun-mt-12 codefun-flex-col section_3"> <view class="codefun-mt-12 codefun-flex-col section_3">
<view class="codefun-flex-row codefun-justify-between group_4"> <view class="codefun-flex-row codefun-justify-between group_4">
<view class="codefun-flex-row codefun-self-start"> <view class="codefun-flex-row codefun-self-start">
<image <image class="codefun-shrink-0 image_7"
class="codefun-shrink-0 image_7" src="/static/images/codefun/db26a8ae3f4d5f1e0a3f11d8fb5bc491.png" />
src="/static/images/codefun/db26a8ae3f4d5f1e0a3f11d8fb5bc491.png"
/>
<view <view
class="codefun-flex-col codefun-items-start codefun-shrink-0 codefun-self-center group_7" class="codefun-flex-col codefun-items-start codefun-shrink-0 codefun-self-center group_7">
>
<text class="text_5">{{ pageData.total }}</text> <text class="text_5">{{ pageData.total }}</text>
<text class="font_4 text_7 mt-5">总基地数</text> <text class="font_4 text_7 mt-5">总基地数</text>
</view> </view>
...@@ -115,34 +107,26 @@ function getList() { ...@@ -115,34 +107,26 @@ function getList() {
</view> </view>
<view class="codefun-flex-col codefun-self-center group_5"> <view class="codefun-flex-col codefun-self-center group_5">
<view class="codefun-flex-row codefun-items-center group_6"> <view class="codefun-flex-row codefun-items-center group_6">
<image <image class="image_6"
class="image_6" src="/static/images/codefun/118c884c539aaba710313f0682db00e1.png" />
src="/static/images/codefun/118c884c539aaba710313f0682db00e1.png"
/>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper" class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper">
>
<text class="font_3 text_6">已认证:</text> <text class="font_3 text_6">已认证:</text>
</view> </view>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_2" class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_2">
>
<text class="font_5">{{ pageData.type_success_total }}</text> <text class="font_5">{{ pageData.type_success_total }}</text>
</view> </view>
</view> </view>
<view class="codefun-flex-row codefun-items-center group_8"> <view class="codefun-flex-row codefun-items-center group_8">
<image <image class="image_6"
class="image_6" src="/static/images/codefun/27ef797870c2085d1a14446c50cf53e0.png" />
src="/static/images/codefun/27ef797870c2085d1a14446c50cf53e0.png"
/>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper" class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper">
>
<text class="font_3 text_6">待认证:</text> <text class="font_3 text_6">待认证:</text>
</view> </view>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_3" class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_3">
>
<text class="font_3 text_8">{{ pageData.type_unverified_total }}</text> <text class="font_3 text_8">{{ pageData.type_unverified_total }}</text>
</view> </view>
</view> </view>
...@@ -152,8 +136,7 @@ function getList() { ...@@ -152,8 +136,7 @@ function getList() {
<view class="codefun-flex-row"> <view class="codefun-flex-row">
<image class="image_8" src="/static/images/codefun/c24e87154a833caadfcb70fb24ae52dc.png" /> <image class="image_8" src="/static/images/codefun/c24e87154a833caadfcb70fb24ae52dc.png" />
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-start text-wrapper_4" class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-start text-wrapper_4">
>
<text class="font_5">基地认证指南</text> <text class="font_5">基地认证指南</text>
</view> </view>
</view> </view>
...@@ -162,15 +145,11 @@ function getList() { ...@@ -162,15 +145,11 @@ function getList() {
</view> </view>
<view class="codefun-mt-12 codefun-flex-col section_4" v-if="pageData.list.length"> <view class="codefun-mt-12 codefun-flex-col section_4" v-if="pageData.list.length">
<view class="codefun-flex-col codefun-self-stretch list"> <view class="codefun-flex-col codefun-self-stretch list">
<view <view class="codefun-flex-row codefun-items-center list-item"
class="codefun-flex-row codefun-items-center list-item" v-for="(item, index) in pageData.list" :key="index">
v-for="(item, index) in pageData.list"
:key="index"
>
<view class="codefun-flex-col codefun-justify-start codefun-items-start section_5"> <view class="codefun-flex-col codefun-justify-start codefun-items-start section_5">
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_5" class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_5">
>
<text class="font_6">{{ item.auditStatus_dictText }}</text> <text class="font_6">{{ item.auditStatus_dictText }}</text>
</view> </view>
</view> </view>
...@@ -183,24 +162,18 @@ function getList() { ...@@ -183,24 +162,18 @@ function getList() {
</view> </view>
</view> </view>
<view <view
class="codefun-mt-18 codefun-flex-row codefun-justify-between codefun-items-center group_11" class="codefun-mt-18 codefun-flex-row codefun-justify-between codefun-items-center group_11">
>
<view class="codefun-flex-row" @click="goDetail(item.id)"> <view class="codefun-flex-row" @click="goDetail(item.id)">
<image <image class="image_10"
class="image_10" src="/static/images/codefun/3566724e23f8a91e60ae87c2744e4090.png" />
src="/static/images/codefun/3566724e23f8a91e60ae87c2744e4090.png"
/>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_6" class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_6">
>
<text class="font_7 text_11">详情</text> <text class="font_7 text_11">详情</text>
</view> </view>
</view> </view>
<view class="codefun-flex-row codefun-items-center" @click="del(item.id)"> <view class="codefun-flex-row codefun-items-center" @click="del(item.id)">
<image <image class="codefun-shrink-0 image_10"
class="codefun-shrink-0 image_10" src="/static/images/codefun/8630d19ebb6334e2028daa7d7b8b5983.png" />
src="/static/images/codefun/8630d19ebb6334e2028daa7d7b8b5983.png"
/>
<text class="font_8 ml-5">删除</text> <text class="font_8 ml-5">删除</text>
</view> </view>
</view> </view>
...@@ -214,31 +187,31 @@ function getList() { ...@@ -214,31 +187,31 @@ function getList() {
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
body { body {
background-color: #e6f5e8; background-color: #e6f5e8;
} }
.mt-5 { .mt-5 {
margin-top: 10rpx; margin-top: 10rpx;
} }
.mt-11 { .mt-11 {
margin-top: 22rpx; margin-top: 22rpx;
} }
.ml-5 { .ml-5 {
margin-left: 10rpx; margin-left: 10rpx;
} }
.ml-13 { .ml-13 {
margin-left: 26rpx; margin-left: 26rpx;
} }
.ml-9 { .ml-9 {
margin-left: 18rpx; margin-left: 18rpx;
} }
.page { .page {
background-color: #e6f5e8; background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 100%; width: 100%;
...@@ -701,5 +674,5 @@ function getList() { ...@@ -701,5 +674,5 @@ function getList() {
line-height: 25.76rpx; line-height: 25.76rpx;
color: #ffffff; color: #ffffff;
} }
} }
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app' import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import * as WodeAPI from '@/api/model/wode' import * as WodeAPI from '@/api/model/wode'
import * as NongchangAPI from '@/api/model/nongchang' import * as NongchangAPI from '@/api/model/nongchang'
import SaveDialog from '../device/components/save-dialog.vue'
// 下拉刷新 // 下拉刷新
onPullDownRefresh(() => { onPullDownRefresh(() => {
setTimeout(function () { setTimeout(function () {
uni.stopPullDownRefresh() uni.stopPullDownRefresh()
Message.toast('刷新成功') Message.toast('刷新成功')
}, 1000) }, 1000)
}) })
onLoad(() => { onLoad(() => {
getBizCommonFileList() getBizCommonFileList()
getFarmsList() getFarmsList()
}) })
// 页面数据 // 页面数据
const pageData = reactive({ const pageData = reactive({
// 用户信息 // 用户信息
userInfo: { userInfo: {
avatar: '/static/images/codefun/8653455b786fbf94ae1c3946f11e7d40.png', avatar: '/static/images/codefun/8653455b786fbf94ae1c3946f11e7d40.png',
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
status: '离线可用', status: '离线可用',
statusClass: 'text_14', statusClass: 'text_14',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png', arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
url: ''
}, },
{ {
id: 2, id: 2,
...@@ -69,6 +70,7 @@ ...@@ -69,6 +70,7 @@
actionText: '添加设备', actionText: '添加设备',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png', arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
addIcon: '/static/images/codefun/2ff61f748e26b18760ca166aa8cfa15a.png', addIcon: '/static/images/codefun/2ff61f748e26b18760ca166aa8cfa15a.png',
url: '/pages/device/device'
}, },
], ],
...@@ -165,9 +167,9 @@ ...@@ -165,9 +167,9 @@
}, },
], ],
}, },
}) })
function getBizCommonFileList() { function getBizCommonFileList() {
WodeAPI.bizCommonFileList({ WodeAPI.bizCommonFileList({
pageNo: 1, pageNo: 1,
pageSize: 4, pageSize: 4,
...@@ -175,13 +177,13 @@ ...@@ -175,13 +177,13 @@
const { records } = res const { records } = res
pageData.commonResources.resources = records pageData.commonResources.resources = records
}) })
} }
function getFarmBaseList(id) { function getFarmBaseList(id) {
NongchangAPI.getFarmBaseList({ id }).then((res) => { NongchangAPI.getFarmBaseList({ id }).then((res) => {
pageData.statistics[0].value = res.length pageData.statistics[0].value = res.length
}) })
} }
function getFarmsList() { function getFarmsList() {
NongchangAPI.farmsList({ NongchangAPI.farmsList({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
...@@ -198,34 +200,51 @@ ...@@ -198,34 +200,51 @@
getFarmBaseList(pageData.userInfo.ncId) getFarmBaseList(pageData.userInfo.ncId)
}) })
} }
// 用户信息设置点击事件 // 用户信息设置点击事件
function onSettingsClick() { function onSettingsClick() {
console.log('点击设置') console.log('点击设置')
// 在这里添加具体的设置点击逻辑 // 在这里添加具体的设置点击逻辑
} }
// 消息中心点击事件 // 消息中心点击事件
function onMessageCenterClick() { function onMessageCenterClick() {
console.log('点击消息中心') console.log('点击消息中心')
// 在这里添加具体的消息中心点击逻辑 // 在这里添加具体的消息中心点击逻辑
} }
// 功能模块点击事件 // 功能模块点击事件
function onFeatureClick(feature: any) { function onFeatureClick(feature: any) {
console.log('点击功能模块:', feature) console.log('点击功能模块:', feature)
// 在这里添加具体的功能模块点击逻辑 // 在这里添加具体的功能模块点击逻辑
} uni.navigateTo({
url: feature.url,
})
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
})
const showAddDialog = () => {
currentEditData.value = null
showDialog.value = true
}
const onAddClick = (feature: any) => {
console.log('点击功能模块:', feature)
if (feature.id === 2) showAddDialog()
// 常用资源点击事件 }
function onResourceClick(resource: any) { // 常用资源点击事件
function onResourceClick(resource: any) {
console.log('点击资源:', resource) console.log('点击资源:', resource)
// 在这里添加具体的资源点击逻辑 // 在这里添加具体的资源点击逻辑
} }
// 资源下载点击事件 // 资源下载点击事件
function onDownloadClick(resource: any) { function onDownloadClick(resource: any) {
// 阻止事件冒泡 // 阻止事件冒泡
event?.stopPropagation() event?.stopPropagation()
...@@ -243,10 +262,10 @@ ...@@ -243,10 +262,10 @@
/* #ifndef H5 */ /* #ifndef H5 */
downloadFileForNative(resource) downloadFileForNative(resource)
/* #endif */ /* #endif */
} }
// H5平台下载文件函数 // H5平台下载文件函数
function downloadFileForWeb(resource: any) { function downloadFileForWeb(resource: any) {
const url = resource.fileSrc const url = resource.fileSrc
// 创建一个临时的a标签用于下载 // 创建一个临时的a标签用于下载
...@@ -263,10 +282,10 @@ ...@@ -263,10 +282,10 @@
document.body.removeChild(link) document.body.removeChild(link)
uni.hideLoading() uni.hideLoading()
Message.toast('开始下载') Message.toast('开始下载')
} }
// 原生平台下载文件函数 // 原生平台下载文件函数
function downloadFileForNative(resource: any) { function downloadFileForNative(resource: any) {
uni.downloadFile({ uni.downloadFile({
url: resource.fileSrc, url: resource.fileSrc,
success: (res) => { success: (res) => {
...@@ -312,37 +331,37 @@ ...@@ -312,37 +331,37 @@
Message.toast('网络错误,下载失败') Message.toast('网络错误,下载失败')
}, },
}) })
} }
// 查看所有资源 // 查看所有资源
function onViewAllResources() { function onViewAllResources() {
console.log('查看所有资源') console.log('查看所有资源')
// 在这里添加具体的查看所有资源逻辑 // 在这里添加具体的查看所有资源逻辑
} }
// 我的设备标题点击事件 // 我的设备标题点击事件
function onMyDevicesTitleClick() { function onMyDevicesTitleClick() {
console.log('点击我的设备标题') console.log('点击我的设备标题')
// 在这里添加具体的设备标题点击逻辑 // 在这里添加具体的设备标题点击逻辑
} }
// 设备点击事件 // 设备点击事件
function onDeviceClick(device: any) { function onDeviceClick(device: any) {
console.log('点击设备:', device) console.log('点击设备:', device)
// 在这里添加具体的设备点击逻辑 // 在这里添加具体的设备点击逻辑
} }
// 客服点击事件 // 客服点击事件
function onServiceClick(service: any) { function onServiceClick(service: any) {
console.log('点击客服:', service) console.log('点击客服:', service)
// 在这里添加具体的客服点击逻辑 // 在这里添加具体的客服点击逻辑
} }
// 帮助点击事件 // 帮助点击事件
function onHelpClick(help: any) { function onHelpClick(help: any) {
console.log('点击帮助:', help) console.log('点击帮助:', help)
// 在这里添加具体的帮助点击逻辑 // 在这里添加具体的帮助点击逻辑
} }
</script> </script>
<template> <template>
...@@ -356,18 +375,13 @@ ...@@ -356,18 +375,13 @@
<view class="codefun-flex-row codefun-items-center codefun-self-stretch"> <view class="codefun-flex-row codefun-items-center codefun-self-stretch">
<text class="font_2 text_2">{{ pageData.userInfo.farmName }}</text> <text class="font_2 text_2">{{ pageData.userInfo.farmName }}</text>
<view <view
class="codefun-flex-row codefun-items-center codefun-shrink-0 section_2 codefun-ml-6" class="codefun-flex-row codefun-items-center codefun-shrink-0 section_2 codefun-ml-6">
> <image v-show="pageData.userInfo.certification.icon"
<image
v-show="pageData.userInfo.certification.icon"
class="codefun-shrink-0 image_7 mr-1" class="codefun-shrink-0 image_7 mr-1"
:src="pageData.userInfo.certification.icon" :src="pageData.userInfo.certification.icon" />
/> <text class="font_3 text_3"
<text :style="{ color: pageData.userInfo.certification.icon ? '' : '#fbc428' }">{{
class="font_3 text_3" pageData.userInfo.certification.text }}</text>
:style="{ color: pageData.userInfo.certification.icon ? '' : '#fbc428' }"
>{{ pageData.userInfo.certification.text }}</text
>
</view> </view>
</view> </view>
<text class="codefun-self-start font_1 codefun-mt-10">{{ <text class="codefun-self-start font_1 codefun-mt-10">{{
...@@ -379,15 +393,9 @@ ...@@ -379,15 +393,9 @@
</view> </view>
<view class="codefun-flex-col codefun-justify-start section_3"> <view class="codefun-flex-col codefun-justify-start section_3">
<view class="codefun-flex-row"> <view class="codefun-flex-row">
<navigator <navigator v-for="stat in pageData.statistics" :url="stat.url" :key="stat.id"
v-for="stat in pageData.statistics" class="codefun-flex-col codefun-items-center group_6 equal-division-item" hover-class="none"
:url="stat.url" :render-link="false" :class="{ 'codefun-ml-32': stat.id > 1 }">
:key="stat.id"
class="codefun-flex-col codefun-items-center group_6 equal-division-item"
hover-class="none"
:render-link="false"
:class="{ 'codefun-ml-32': stat.id > 1 }"
>
<text class="font_4">{{ stat.value }}</text> <text class="font_4">{{ stat.value }}</text>
<text class="font_5 codefun-mt-16">{{ stat.label }}</text> <text class="font_5 codefun-mt-16">{{ stat.label }}</text>
</navigator> </navigator>
...@@ -396,17 +404,15 @@ ...@@ -396,17 +404,15 @@
</view> </view>
<view class="codefun-flex-col codefun-relative group_7"> <view class="codefun-flex-col codefun-relative group_7">
<view class="codefun-flex-col"> <view class="codefun-flex-col">
<view <!-- 消息中心 -->
class="codefun-flex-row codefun-justify-between codefun-items-center section_12" <view class="codefun-flex-row codefun-justify-between codefun-items-center section_12"
@click="onMessageCenterClick" @click="onMessageCenterClick">
>
<view class="codefun-flex-row group_8"> <view class="codefun-flex-row group_8">
<image class="image_10" :src="pageData.messageCenter.icon" /> <image class="image_10" :src="pageData.messageCenter.icon" />
<view class="codefun-flex-col group_9 codefun-ml-12"> <view class="codefun-flex-col group_9 codefun-ml-12">
<text class="codefun-self-start font">{{ pageData.messageCenter.title }}</text> <text class="codefun-self-start font">{{ pageData.messageCenter.title }}</text>
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-start codefun-self-stretch text-wrapper_2 codefun-mt-4" class="codefun-flex-col codefun-justify-start codefun-items-start codefun-self-stretch text-wrapper_2 codefun-mt-4">
>
<text class="font_7">{{ pageData.messageCenter.description }}</text> <text class="font_7">{{ pageData.messageCenter.description }}</text>
</view> </view>
</view> </view>
...@@ -418,14 +424,11 @@ ...@@ -418,14 +424,11 @@
<image class="image_11 codefun-ml-12" :src="pageData.messageCenter.arrowIcon" /> <image class="image_11 codefun-ml-12" :src="pageData.messageCenter.arrowIcon" />
</view> </view>
</view> </view>
<!-- 资源/设备 -->
<view class="codefun-flex-row equal-division codefun-mt-12"> <view class="codefun-flex-row equal-division codefun-mt-12">
<view <view v-for="(feature, index) in pageData.features" :key="feature.id"
v-for="(feature, index) in pageData.features" class="codefun-flex-col section_5 section_11" :class="{ 'codefun-ml-12': index > 0 }"
:key="feature.id" @click="onFeatureClick(feature)">
class="codefun-flex-col section_5 section_11"
:class="{ 'codefun-ml-12': index > 0 }"
@click="onFeatureClick(feature)"
>
<view class="codefun-flex-row codefun-self-stretch"> <view class="codefun-flex-row codefun-self-stretch">
<view class="codefun-flex-row codefun-items-center codefun-flex-1"> <view class="codefun-flex-row codefun-items-center codefun-flex-1">
<image class="codefun-shrink-0 image_10" :src="feature.icon" /> <image class="codefun-shrink-0 image_10" :src="feature.icon" />
...@@ -434,33 +437,27 @@ ...@@ -434,33 +437,27 @@
<text class="font_8 codefun-mt-8">{{ feature.count }}</text> <text class="font_8 codefun-mt-8">{{ feature.count }}</text>
</view> </view>
</view> </view>
<image <image class="codefun-shrink-0 codefun-self-start image_11" :class="{
class="codefun-shrink-0 codefun-self-start image_11"
:class="{
image_12: feature.id === 1, image_12: feature.id === 1,
image_13: feature.id === 2, image_13: feature.id === 2,
'codefun-ml-8': feature.id === 1, 'codefun-ml-8': feature.id === 1,
}" }" :src="feature.arrowIcon" />
:src="feature.arrowIcon"
/>
</view> </view>
<text class="codefun-self-stretch font_7 codefun-mt-10">{{ feature.description }}</text> <text class="codefun-self-stretch font_7 codefun-mt-10">{{ feature.description }}</text>
<view <view v-if="feature.status"
v-if="feature.status" class="codefun-flex-col codefun-justify-start codefun-items-center codefun-self-start view mt-2">
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-self-start view mt-2"
>
<text class="font_6" :class="feature.statusClass">{{ feature.status }}</text> <text class="font_6" :class="feature.statusClass">{{ feature.status }}</text>
</view> </view>
<view <view v-if="feature.actionText && feature.addIcon"
v-if="feature.actionText && feature.addIcon"
class="codefun-flex-row codefun-justify-evenly codefun-items-center codefun-self-start view_2 mt-2" class="codefun-flex-row codefun-justify-evenly codefun-items-center codefun-self-start view_2 mt-2"
> @click.stop="onAddClick(feature)">
<image class="image_14" :src="feature.addIcon" /> <image class="image_14" :src="feature.addIcon" />
<text class="font_3">{{ feature.actionText }}</text> <text class="font_3">{{ feature.actionText }}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="codefun-flex-col codefun-mt-24"> <view class="codefun-flex-col codefun-mt-24">
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_13"> <view class="codefun-flex-row codefun-justify-between codefun-items-center group_13">
<text class="font_2">{{ pageData.commonResources.title }}</text> <text class="font_2">{{ pageData.commonResources.title }}</text>
...@@ -471,10 +468,8 @@ ...@@ -471,10 +468,8 @@
<view class="codefun-flex-col list"> <view class="codefun-flex-col list">
<view <view
class="codefun-flex-row codefun-justify-between codefun-items-center list-item codefun-mt-24" class="codefun-flex-row codefun-justify-between codefun-items-center list-item codefun-mt-24"
v-for="resource in pageData.commonResources.resources" v-for="resource in pageData.commonResources.resources" :key="resource.id"
:key="resource.id" @click="onResourceClick(resource)">
@click="onResourceClick(resource)"
>
<view class="codefun-flex-row"> <view class="codefun-flex-row">
<image class="image_15" :src="pageData.commonResources.icon[resource.fileType]?.icon" /> <image class="image_15" :src="pageData.commonResources.icon[resource.fileType]?.icon" />
<view class="codefun-flex-col codefun-items-start group_14 codefun-ml-12"> <view class="codefun-flex-col codefun-items-start group_14 codefun-ml-12">
...@@ -482,10 +477,8 @@ ...@@ -482,10 +477,8 @@
<text class="font_6 codefun-mt-12">{{ resource.fileSize }}</text> <text class="font_6 codefun-mt-12">{{ resource.fileSize }}</text>
</view> </view>
</view> </view>
<view <view class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4" @click.stop="onDownloadClick(resource)">
@click.stop="onDownloadClick(resource)"
>
<text class="font_10">下载</text> <text class="font_10">下载</text>
</view> </view>
</view> </view>
...@@ -500,13 +493,9 @@ ...@@ -500,13 +493,9 @@
</view> </view>
<view class="codefun-flex-col codefun-mt-16"> <view class="codefun-flex-col codefun-mt-16">
<view class="codefun-flex-col section_12"> <view class="codefun-flex-col section_12">
<view <view class="codefun-flex-row codefun-justify-between codefun-items-center"
class="codefun-flex-row codefun-justify-between codefun-items-center" v-for="(device, index) in pageData.myDevices.devices" :key="device.id"
v-for="(device, index) in pageData.myDevices.devices" :class="{ 'codefun-mt-16': index > 0 }" @click="onDeviceClick(device)">
:key="device.id"
:class="{ 'codefun-mt-16': index > 0 }"
@click="onDeviceClick(device)"
>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="image_17" :src="device.image" /> <image class="image_17" :src="device.image" />
<view class="codefun-flex-col codefun-items-start codefun-ml-8"> <view class="codefun-flex-col codefun-items-start codefun-ml-8">
...@@ -516,23 +505,17 @@ ...@@ -516,23 +505,17 @@
</view> </view>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="codefun-shrink-0 image_18" :src="device.statusIcon" /> <image class="codefun-shrink-0 image_18" :src="device.statusIcon" />
<text <text class="font_6" :class="device.statusClass || ''"
class="font_6" :style="{ color: device.status === '正常' ? '#13e000' : '#999999' }">
:class="device.statusClass || ''"
:style="{ color: device.status === '正常' ? '#13e000' : '#999999' }"
>
{{ device.status }} {{ device.status }}
</text> </text>
</view> </view>
</view> </view>
</view> </view>
<view class="codefun-flex-col section_9 codefun-mt-12"> <view class="codefun-flex-col section_9 codefun-mt-12">
<view <view class="codefun-flex-row codefun-justify-between codefun-items-center"
class="codefun-flex-row codefun-justify-between codefun-items-center" v-for="service in pageData.support.services" :key="service.id"
v-for="service in pageData.support.services" @click="onServiceClick(service)">
:key="service.id"
@click="onServiceClick(service)"
>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="codefun-shrink-0 image_19" :src="service.icon" /> <image class="codefun-shrink-0 image_19" :src="service.icon" />
<text class="font_13 codefun-ml-8">{{ service.title }}</text> <text class="font_13 codefun-ml-8">{{ service.title }}</text>
...@@ -540,13 +523,9 @@ ...@@ -540,13 +523,9 @@
<image class="image_20" :src="service.arrowIcon" /> <image class="image_20" :src="service.arrowIcon" />
</view> </view>
<view class="codefun-flex-col codefun-mt-20"> <view class="codefun-flex-col codefun-mt-20">
<view <view class="codefun-flex-row codefun-justify-between codefun-items-center"
class="codefun-flex-row codefun-justify-between codefun-items-center" v-for="help in pageData.support.helps" :key="help.id"
v-for="help in pageData.support.helps" :class="{ 'codefun-mt-20': help.id > 1 }" @click="onHelpClick(help)">
:key="help.id"
:class="{ 'codefun-mt-20': help.id > 1 }"
@click="onHelpClick(help)"
>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="codefun-shrink-0 image_21" :src="help.icon" /> <image class="codefun-shrink-0 image_21" :src="help.icon" />
<text class="font_13 codefun-ml-8">{{ help.title }}</text> <text class="font_13 codefun-ml-8">{{ help.title }}</text>
...@@ -559,11 +538,13 @@ ...@@ -559,11 +538,13 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 弹窗组件 -->
<save-dialog :show="showDialog" :editData="currentEditData" @update:show="showDialog = $event" />
</view> </view>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.page { .page {
background-color: #e6f5e8; background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 100%; width: 100%;
...@@ -578,41 +559,50 @@ ...@@ -578,41 +559,50 @@
background-image: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png'); background-image: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png');
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
.group_2 { .group_2 {
margin-right: 8rpx; margin-right: 8rpx;
padding: 0 12rpx; padding: 0 12rpx;
.image { .image {
border-radius: 64rpx; border-radius: 64rpx;
width: 108rpx; width: 108rpx;
height: 42rpx; height: 42rpx;
} }
.image_2 { .image_2 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 34rpx; width: 34rpx;
height: 22rpx; height: 22rpx;
} }
.image_3 { .image_3 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 30rpx; width: 30rpx;
height: 22rpx; height: 22rpx;
} }
.image_4 { .image_4 {
width: 48rpx; width: 48rpx;
height: 22rpx; height: 22rpx;
} }
} }
.group_3 { .group_3 {
margin-right: 8rpx; margin-right: 8rpx;
margin-top: 42rpx; margin-top: 42rpx;
padding: 16rpx 8rpx 0; padding: 16rpx 8rpx 0;
.text { .text {
color: #ffffffe6; color: #ffffffe6;
} }
.image_5 { .image_5 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 44rpx; width: 44rpx;
height: 42rpx; height: 42rpx;
} }
.pos { .pos {
position: absolute; position: absolute;
right: 8rpx; right: 8rpx;
...@@ -620,6 +610,7 @@ ...@@ -620,6 +610,7 @@
transform: translateY(-50%); transform: translateY(-50%);
} }
} }
.group_4 { .group_4 {
.image_6 { .image_6 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
...@@ -627,33 +618,40 @@ ...@@ -627,33 +618,40 @@
width: 96rpx; width: 96rpx;
height: 96rpx; height: 96rpx;
} }
.group_5 { .group_5 {
margin-top: 8rpx; margin-top: 8rpx;
margin-bottom: 8rpx; margin-bottom: 8rpx;
.text_2 { .text_2 {
color: #ffffff; color: #ffffff;
} }
.section_2 { .section_2 {
padding: 8rpx; padding: 8rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 400rpx; border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
height: 42rpx; height: 42rpx;
.image_7 { .image_7 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 18rpx; width: 18rpx;
height: 12rpx; height: 12rpx;
} }
.text_3 { .text_3 {
font-size: 22rpx; font-size: 22rpx;
line-height: 22rpx; line-height: 22rpx;
} }
} }
} }
.image_9 { .image_9 {
margin-right: 8rpx; margin-right: 8rpx;
} }
} }
.section_3 { .section_3 {
margin-right: 16rpx; margin-right: 16rpx;
margin-top: 24rpx; margin-top: 24rpx;
...@@ -661,14 +659,17 @@ ...@@ -661,14 +659,17 @@
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.group_6 { .group_6 {
flex: 1 1 186.88rpx; flex: 1 1 186.88rpx;
.font_4 { .font_4 {
font-size: 36rpx; font-size: 36rpx;
line-height: 36rpx; line-height: 36rpx;
font-weight: 600; font-weight: 600;
color: #20602d; color: #20602d;
} }
.font_5 { .font_5 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
...@@ -677,24 +678,29 @@ ...@@ -677,24 +678,29 @@
} }
} }
} }
.group_7 { .group_7 {
margin-top: -64rpx; margin-top: -64rpx;
padding: 0 20rpx; padding: 0 20rpx;
.section_12 { .section_12 {
margin-right: 16rpx; margin-right: 16rpx;
padding: 24rpx; padding: 24rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.group_8 { .group_8 {
overflow: hidden; overflow: hidden;
width: 411.4rpx; width: 411.4rpx;
height: 80rpx; height: 80rpx;
.group_9 { .group_9 {
padding-top: 8rpx; padding-top: 8rpx;
overflow: hidden; overflow: hidden;
width: 307.4rpx; width: 307.4rpx;
height: 80rpx; height: 80rpx;
.text-wrapper_2 { .text-wrapper_2 {
padding: 8rpx 0; padding: 8rpx 0;
overflow: hidden; overflow: hidden;
...@@ -702,8 +708,10 @@ ...@@ -702,8 +708,10 @@
} }
} }
} }
.group_10 { .group_10 {
margin-right: 8rpx; margin-right: 8rpx;
.text-wrapper { .text-wrapper {
padding: 8rpx 0; padding: 8rpx 0;
background-color: #ff5454; background-color: #ff5454;
...@@ -713,53 +721,66 @@ ...@@ -713,53 +721,66 @@
height: 40rpx; height: 40rpx;
} }
} }
.image_17 { .image_17 {
border-radius: 24rpx; border-radius: 24rpx;
width: 92rpx; width: 92rpx;
height: 92rpx; height: 92rpx;
} }
.font_11 { .font_11 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
color: #15161a; color: #15161a;
} }
.image_18 { .image_18 {
width: 72rpx; width: 72rpx;
height: 12rpx; height: 12rpx;
} }
.text_24 { .text_24 {
color: #13e000; color: #13e000;
} }
} }
.equal-division { .equal-division {
margin-right: 16rpx; margin-right: 16rpx;
.section_5 { .section_5 {
flex: 1 1 336rpx; flex: 1 1 336rpx;
.font_8 { .font_8 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #4cd964; color: #4cd964;
} }
.image_12 { .image_12 {
margin-right: 8rpx; margin-right: 8rpx;
margin-top: 8rpx; margin-top: 8rpx;
} }
.view { .view {
padding: 12rpx 16rpx; padding: 12rpx 16rpx;
border-radius: 12rpx; border-radius: 12rpx;
overflow: hidden; overflow: hidden;
background-color: #4fc5fd33; background-color: #4fc5fd33;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.text_14 { .text_14 {
color: #4fbdfb; color: #4fbdfb;
} }
} }
.group_12 { .group_12 {
margin-left: 16rpx; margin-left: 16rpx;
} }
.image_13 { .image_13 {
margin: 8rpx 8rpx 0 40rpx; margin: 8rpx 8rpx 0 40rpx;
} }
.view_2 { .view_2 {
padding: 12rpx 16rpx; padding: 12rpx 16rpx;
border-radius: 12rpx; border-radius: 12rpx;
...@@ -767,12 +788,14 @@ ...@@ -767,12 +788,14 @@
background-color: rgba(93, 182, 111, 0.2); background-color: rgba(93, 182, 111, 0.2);
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 152rpx; width: 152rpx;
.image_14 { .image_14 {
width: 20rpx; width: 20rpx;
height: 20rpx; height: 20rpx;
} }
} }
} }
.section_11 { .section_11 {
padding: 20rpx 24rpx; padding: 20rpx 24rpx;
background-color: #ffffff; background-color: #ffffff;
...@@ -781,55 +804,67 @@ ...@@ -781,55 +804,67 @@
height: 220rpx; height: 220rpx;
} }
} }
.image_10 { .image_10 {
border-radius: 16rpx; border-radius: 16rpx;
width: 80rpx; width: 80rpx;
height: 80rpx; height: 80rpx;
} }
.image_11 { .image_11 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 12rpx; width: 12rpx;
height: 22rpx; height: 22rpx;
} }
.font_7 { .font_7 {
font-size: 22rpx; font-size: 22rpx;
line-height: 22rpx; line-height: 22rpx;
color: #6b7280; color: #6b7280;
} }
.group_13 { .group_13 {
padding-bottom: 32rpx; padding-bottom: 32rpx;
.text_16 { .text_16 {
margin-right: 8rpx; margin-right: 8rpx;
} }
} }
.list { .list {
margin-right: 16rpx; margin-right: 16rpx;
padding: 32rpx 24rpx; padding: 32rpx 24rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.list-item { .list-item {
&:first-child { &:first-child {
margin-top: 0; margin-top: 0;
} }
.image_15 { .image_15 {
width: 54rpx; width: 54rpx;
height: 72rpx; height: 72rpx;
} }
.group_14 { .group_14 {
margin-top: 8rpx; margin-top: 8rpx;
.font_9 { .font_9 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
color: #333333; color: #333333;
} }
} }
.text-wrapper_4 { .text-wrapper_4 {
padding: 16rpx 0; padding: 16rpx 0;
background-color: #5db66f26; background-color: #5db66f26;
border-radius: 400rpx; border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 136rpx; width: 136rpx;
.font_10 { .font_10 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
...@@ -838,65 +873,79 @@ ...@@ -838,65 +873,79 @@
} }
} }
} }
.font_6 { .font_6 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #999999; color: #999999;
} }
.text_22 { .text_22 {
margin-right: 16rpx; margin-right: 16rpx;
} }
.section_9 { .section_9 {
margin-right: 16rpx; margin-right: 16rpx;
padding: 28rpx 24rpx; padding: 28rpx 24rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.image_19 { .image_19 {
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
} }
.font_13 { .font_13 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
color: #1d2129; color: #1d2129;
} }
.image_21 { .image_21 {
width: 38rpx; width: 38rpx;
height: 38rpx; height: 38rpx;
} }
} }
} }
.font { .font {
font-size: 32rpx; font-size: 32rpx;
line-height: 32rpx; line-height: 32rpx;
color: #000000; color: #000000;
} }
.font_1 { .font_1 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #ffffff; color: #ffffff;
} }
.font_3 { .font_3 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #5db66f; color: #5db66f;
} }
.font_2 { .font_2 {
font-size: 32rpx; font-size: 32rpx;
line-height: 32rpx; line-height: 32rpx;
font-weight: 600; font-weight: 600;
color: #333333; color: #333333;
} }
.image_8 { .image_8 {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
} }
} }
.equal-division_2 { .equal-division_2 {
margin-right: 8rpx; margin-right: 8rpx;
.group_15 { .group_15 {
flex: 1 1 148.4rpx; flex: 1 1 148.4rpx;
.font_14 { .font_14 {
font-size: 20rpx; font-size: 20rpx;
line-height: 20rpx; line-height: 20rpx;
...@@ -904,18 +953,21 @@ ...@@ -904,18 +953,21 @@
} }
} }
} }
.section_6 { .section_6 {
padding: 16rpx 0; padding: 16rpx 0;
background-color: #ffffff; background-color: #ffffff;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
border-top: solid 1rpx #e7e7e7; border-top: solid 1rpx #e7e7e7;
} }
.equal-division-item { .equal-division-item {
padding: 8rpx 0; padding: 8rpx 0;
} }
.image_20 { .image_20 {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
} }
} }
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论