| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- <template>
- <view class="home-search">
- <!-- 搜索悬浮按钮 -->
- <view class="home-search__search">
- <view
- :duration="300"
- mode="fade-right"
- :timing-function="'ease-in-out'"
- customStyle="flex:1 1 auto;"
- style="width:100%"
- v-show="showSearch"
- ><view class="search-bar" :animation="searchAnim">
- <view class="search-bar-btn">
- <view
- class="search-select"
- @click="handleTypeClick"
- >
- <text>{{ searchTypeName }}</text>
- <u-icon name="arrow-down" size="24" class="icon"></u-icon>
- </view>
- <u-input
- style="width:80%"
- v-model="searchText"
- :auto-blur="true"
- placeholder="搜索"
- class="search-input"
- @confirm="onSearch"
- >
- </u-input>
- </view>
- </view>
- </view>
-
- <view v-if="!showSearch"></view>
- <button class="layer-btn" @click="openSearch">
- <!-- <u-icon name="search" size="40rpx" color="#364D46"></u-icon> -->
- <image
- mode="aspectFit"
- src="/static/images/home/search.png"
- class="icon"
- />
- <view class="layer-btn__text">搜索</view>
- </button>
- </view>
- <view class="home-search__layer">
- <view></view>
- <button class="layer-btn" @click="handleLayerClick">
- <!-- <u-icon name="search" size="40rpx" color="#364D46"></u-icon> -->
- <!-- <text class="cuIcon-copy icon"></text> -->
- <image
- mode="aspectFit"
- src="/static/images/home/layer.png"
- class="icon"
- />
- <view class="layer-btn__text">图层</view>
- </button>
- </view>
- <view class="home-search__layer">
- <view class="layer-device-status">
- <view class="status-options">
- <view
- class="status-item"
- :class="{ active: deviceStatusCheckedList.includes('1') }"
- @click="toggleDeviceStatus('1')"
- >
- <view class="checkbox">
- <view class="checkbox-inner" v-if="deviceStatusCheckedList.includes('1')">
- <text class="checkmark">
- <u-icon name="checkmark" />
- </text>
- </view>
- </view>
- <text class="status-text">在线</text>
- </view>
-
- <view
- class="status-item"
- :class="{ active: deviceStatusCheckedList.includes('0') }"
- @click="toggleDeviceStatus('0')"
- >
- <view class="checkbox">
- <view class="checkbox-inner" v-if="deviceStatusCheckedList.includes('0')">
- <text class="checkmark">
- <u-icon name="checkmark" />
- </text>
- </view>
- </view>
- <text class="status-text">离线</text>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { isEmpty } from 'lodash-es';
- export default {
- props: {
- layerVisible: {
- type: Boolean,
- default: false
- },
- inputTypeVisible: {
- type: Boolean,
- default: false
- },
- searchTypeName: {
- type: String,
- default: '设备/ID'
- },
- searchType: {
- type: String,
- default: 'device'
- },
- warningData: {
- type: Object,
- default() {
- return {};
- }
- }
- },
- data() {
- return {
- show: false,
- showSearch: true,
- searchTypes: [
- [
- {
- label: '设备/ID',
- value: 'device'
- },
- {
- label: '基地',
- value: 'land'
- },
- {
- label: '地块',
- value: 'block'
- }
- ]
- ],
- searchTypeIndex: 0,
- searchText: '',
- layerDialogVisible: false,
- layerStatus: 'online',
- searchAnim: {},
- currentType: 'land',
- currentTypeName: '基地',
- deviceStatusCheckedList: ['0', '1'],
- title: '',
- description: '',
- layerContainerVisible: true
- };
- },
- computed: {
- hasWarning() {
- return false;
- // return !isEmpty(this.warningData);
- }
- },
- watch: {
- inputTypeVisible(newVal) {
- if (newVal !== this.show) {
- this.show = newVal;
- }
- },
- layerVisible(newVal) {
- if (newVal !== this.layerDialogVisible) {
- this.layerDialogVisible = newVal;
- }
- }
- },
- methods: {
- clickAlert() {
- const msgExtra = JSON.parse(this.warningData.msgExtra);
- const handleId = msgExtra.handleId || '';
- // 跳转消息详情
- uni.navigateTo({
- url:
- '/pages/views/message/detail?msgId=' +
- this.warningData.msgId +
- '&handleId=' +
- handleId
- });
- },
- openSearch() {
- this.showSearch = !this.showSearch;
- this.$nextTick(() => {
- this.searchAnim = uni
- .createAnimation({
- duration: 300,
- timingFunction: 'ease'
- })
- .opacity(1)
- .translateX(0)
- .step()
- .export();
- });
- },
- closeSearch() {
- this.showSearch = false;
- },
- onTypeChange(e) {
- this.searchTypeIndex = e.detail.value;
- },
- onSearch() {
- // 触发搜索逻辑
- this.$emit('search', this.searchText);
- },
- onLayerChange(e) {
- this.layerStatus = e.detail.value;
- },
- openSearchType() {
- this.show = true;
- },
- closeHandler() {
- this.show = false;
- },
- confirmHandler(item) {
- const { value } = item;
- this.currentType = value[0]?.value;
- this.currentTypeName = value[0]?.label;
- this.closeHandler();
- },
- handleLayerClick() {
- this.layerDialogVisible = !this.layerDialogVisible;
- this.$emit('layerChange', this.layerDialogVisible);
- },
- handleTypeClick() {
- this.show = !this.show;
- this.$emit('inputTypeChange', this.show);
- },
- closeAlert() {
- this.layerContainerVisible = false;
- setTimeout(() => {
- this.layerContainerVisible = true;
- });
- },
- handleDeviceStatusChange() {
- this.$nextTick(() => {
- this.$emit('deviceStatusChecked', this.deviceStatusCheckedList);
- });
- },
-
- toggleDeviceStatus(status) {
- const index = this.deviceStatusCheckedList.indexOf(status);
- if (index > -1) {
- this.deviceStatusCheckedList.splice(index, 1);
- } else {
- this.deviceStatusCheckedList.push(status);
- }
- this.handleDeviceStatusChange();
- }
- }
- };
- </script>
- <style scoped lang="scss">
- .home-search {
- position: relative;
- width: 100%;
- pointer-events: none;
- z-index: 401;
- margin-top: 100rpx;
- &__search {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 16rpx;
- height: 88rpx;
- overflow: hidden;
- width: calc(100% - 60rpx);
- }
- &__layer {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- text-align: right;
- pointer-events: none;
- margin-bottom: 16rpx;
- width: calc(100% - 60rpx);
- ::v-deep .u-radio {
- margin-bottom: 16rpx;
- }
- }
- }
- .search-bar {
- display: flex;
- align-items: center;
- background: rgba(255, 255, 255, 0.6);
- border-top-left-radius: 16rpx;
- border-top-right-radius: 16rpx;
- border-bottom-left-radius: 16rpx;
- border-bottom-right-radius: 16rpx;
- padding: 12rpx 16rpx;
- margin-right: 16rpx;
- height: 60rpx;
- pointer-events: auto;
- .search-bar-btn{
- background: rgba(255, 255, 255, 1);
- border-top-left-radius: 8rpx;
- border-top-right-radius: 8rpx;
- border-bottom-left-radius: 8rpx;
- border-bottom-right-radius: 8rpx;
- display: flex;
- align-items: center;
- height: 60rpx;
- }
- }
- .search-type {
- width: 160rpx;
- margin-right: 16rpx;
- }
- .search-input {
- flex: 1;
- width: 100%;
- height: 100%;
- line-height: 60rpx;
- border: none;
- background: #fff;
- font-size: 28rpx;
- }
- .search-btn,
- .close-btn {
- background: none;
- border: none;
- margin-left: 16rpx;
- }
- .fab {
- position: absolute;
- pointer-events: auto;
- box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
- background: #fff;
- border-radius: 50%;
- width: 88rpx;
- height: 88rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .search-fab {
- top: 32rpx;
- left: 32rpx;
- }
- .layer-fab {
- top: 32rpx;
- right: 32rpx;
- }
- ::v-deep .u-checkbox__label {
- font-size: 28rpx;
- color: #fff;
- margin-right: 0;
- }
- .layer-popover {
- position: absolute;
- top: 120rpx;
- right: 32rpx;
- background: #fff;
- border-radius: 16rpx;
- box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.08);
- padding: 24rpx;
- z-index: 20;
- }
- .layer-radio {
- display: block;
- margin-bottom: 16rpx;
- font-size: 28rpx;
- }
- .layer-btn {
- flex: 0 0 auto;
- display: flex;
- flex-direction: column;
- justify-content: center;
- width: 80rpx;
- height: 80rpx;
- padding: 0;
- margin: 0;
- align-items: center;
- text-align: center;
- background: #fff;
- border-radius: 16rpx;
- font-size: 16rpx;
- color: #364d46;
- pointer-events: auto;
- .icon {
- width: 32rpx;
- height: 32rpx;
- font-size: 40rpx;
- line-height: 1;
- color: #364d46;
- margin-bottom: 8rpx;
- }
- &__text {
- font-size: 24rpx;
- line-height: 1;
- }
- }
- .search-select {
- position: relative;
- width: 200rpx;
- font-size: 28rpx;
- color: #042118;
- padding: 0 16rpx;
- margin-right: 16rpx;
- border-right: 1px solid #e4e7ed;
- .icon {
- position: absolute;
- right: 32rpx;
- top: 50%;
- transform: translateY(-50%);
- font-size: 32rpx;
- }
- }
- .layer-device-status {
- pointer-events: auto;
-
- .status-options {
- display: flex;
- flex-direction: column;
- gap: 16rpx;
- }
-
- .status-item {
- display: flex;
- align-items: center;
- gap: 12rpx;
- cursor: pointer;
-
- .checkbox {
- width: 34rpx;
- height: 34rpx;
- border-radius: 10rpx;
- border: 3rpx solid rgba(255, 255, 255, 0.8);
- display: flex;
- align-items: center;
- justify-content: center;
- background: #fff;
- transition: all 0.3s ease;
-
- .checkbox-inner {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- background: #4CAF50;
- display: flex;
- align-items: center;
- justify-content: center;
-
- .checkmark {
- color: white;
- font-size: 24rpx;
- font-weight: bold;
- }
- }
- }
-
- .status-text {
- font-size: 32rpx;
- color: white;
- text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
- }
-
- &.active {
- .checkbox {
- border-color: #4CAF50;
- background: #4CAF50;
- }
- }
- }
- }
- </style>
|