Browse Source

排序问题,排序混乱、数据导出,导出时全部都会导出,无法选择单次数据导出

master
sige 1 year ago
parent
commit
fd2fc90bd3
  1. 8
      .env
  2. 2
      README.md
  3. 20
      publish.ps1
  4. 76
      src/components/Setting/components/History.vue
  5. 4
      src/components/Setting/index.vue
  6. 131
      src/components/dialogs/ClearRecordByKeysModal.vue
  7. 8
      src/main.js
  8. 13
      src/mock/command.js

8
.env

@ -1,5 +1,5 @@
# VITE_BASE_WS1_URL=ws://192.168.8.10:19001/
# VITE_BASE_WS2_URL=ws://192.168.8.10:19002/
VITE_BASE_WS1_URL=ws://192.168.8.10:19001/
VITE_BASE_WS2_URL=ws://192.168.8.10:19002/
VITE_BASE_WS1_URL=ws://127.0.0.1:19001/
VITE_BASE_WS2_URL=ws://127.0.0.1:19002/
# VITE_BASE_WS1_URL=ws://127.0.0.1:19001/
# VITE_BASE_WS2_URL=ws://127.0.0.1:19002/

2
README.md

@ -54,7 +54,7 @@ https://tdesign.tencent.com/
│ └─modules // 分modules │ └─modules // 分modules
├─views // 视图 ├─views // 视图
├─App.vue // 项目根组件 ├─App.vue // 项目根组件
├─main.js // 项目入口
├─main.js // 项目入口yarn
└─style.scss // 全局样式 └─style.scss // 全局样式
``` ```

20
publish.ps1

@ -0,0 +1,20 @@
# build project
yarn build
# rename dist to current time, like 20221215121300
$now = Get-Date -Format "yyyyMMddHHmmss"
Rename-Item -Path ./dist -NewName $now
# compress dist to app.zip
Compress-Archive -Path ./$now -DestinationPath ./app.zip -Force
# upload app.zip to server
scp app.zip root@192.168.8.10:/frontend/
# unzip app.zip
ssh root:zwsd@192.168.8.10 "cd /frontend && unzip app.zip"
# remove old link
ssh root:zwsd@192.168.8.10 "cd /frontend && rm -f dist"
# create link
ssh root:zwsd@192.168.8.10 "cd /frontend && ln -s /frontend/$now /frontend/dist"
# remove app.zip
ssh root:zwsd@192.168.8.10 "cd /frontend && rm -f app.zip"
Remove-Item -Path ./app.zip
# remove folder
Remove-Item -Path ./$now -Recurse

76
src/components/Setting/components/History.vue

@ -2,7 +2,14 @@
<div class="histrory_container"> <div class="histrory_container">
<div class="header_wrap"> <div class="header_wrap">
<p class="title_text">消毒名称</p> <p class="title_text">消毒名称</p>
<p class="operator_text">操作</p>
<p class="operator_text">
<van-dropdown-menu>
<van-dropdown-item title="操作"
:options="[{text:'导出',value:'export'},{text:'删除',value:'delete'}]"
@change="actionOperationExecute"
></van-dropdown-item>
</van-dropdown-menu>
</p>
</div> </div>
<div class="content_wrap" id="set_device_container"> <div class="content_wrap" id="set_device_container">
<img <img
@ -54,16 +61,14 @@
</g> </g>
</svg> </svg>
</div> </div>
<div
class="data_line"
v-for="item in historyStore.historyDataList"
:key="item"
>
<p class="title">{{ item }}</p>
<van-checkbox-group v-model="checkedItems">
<div class="data_line" v-for="item in historyDataList" :key="item">
<p class="title"><van-checkbox :name="item"/> &nbsp; {{ item }}</p>
<div class="btns"> <div class="btns">
<div class="btn" @click="showDetailModal(item)">详情</div> <div class="btn" @click="showDetailModal(item)">详情</div>
</div> </div>
</div> </div>
</van-checkbox-group>
</div> </div>
<div class="detail_modal" v-if="showDetailVisible"> <div class="detail_modal" v-if="showDetailVisible">
<img :src="Top" @click.prevent="topContainer2" class="top_arrow" alt="" /> <img :src="Top" @click.prevent="topContainer2" class="top_arrow" alt="" />
@ -105,21 +110,47 @@
<div class="return_btn" @click="showDetailVisible = false">返回</div> <div class="return_btn" @click="showDetailVisible = false">返回</div>
</div> </div>
</div> </div>
<ClearRecordByKeysModal ref="clearRecordByKeys" :keys="checkedItems"/>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'
import { ref, computed } from 'vue'
import Down from '@/assets/img/arrow/down.png' import Down from '@/assets/img/arrow/down.png'
import Top from '@/assets/img/arrow/top.png' import Top from '@/assets/img/arrow/top.png'
import Right from '@/assets/img/arrow/right.png' import Right from '@/assets/img/arrow/right.png'
import Left from '@/assets/img/arrow/left.png' import Left from '@/assets/img/arrow/left.png'
import { useHistoryStore, useWebSocketStore } from '@/store'
import { getDetailInfoById } from '@/mock/command'
import ClearRecordByKeysModal from 'cpns/dialogs/ClearRecordByKeysModal'
import { useHistoryStore, useWebSocketStore, useSettingStore } from '@/store'
import { getDetailInfoById, exportDisinfectionRecordByKeyListJSON } from '@/mock/command'
const showDetailVisible = ref(false) const showDetailVisible = ref(false)
const historyStore = useHistoryStore() const historyStore = useHistoryStore()
const webSocketStore = useWebSocketStore() const webSocketStore = useWebSocketStore()
const settingStore = useSettingStore()
//
const clearRecordByKeys = ref(null)
//
const checkedItems = ref([])
//
const historyDataList = computed(() => {
return historyStore.historyDataList.sort((a, b) => b.localeCompare(a));
});
//
function actionOperationExecute( action ) {
if ( checkedItems.value.length === 0 ) {
return;
}
if ( 'export' === action ) {
settingStore.updateExportText('导出消毒记录中')
settingStore.updateExportLoading(true)
webSocketStore.sendCommandMsg(exportDisinfectionRecordByKeyListJSON(checkedItems.value));
} else if ( 'delete' === action ) {
clearRecordByKeys.value.showDialog();
}
}
const topContainer = () => { const topContainer = () => {
const ele = document.getElementById('set_device_container') const ele = document.getElementById('set_device_container')
@ -160,7 +191,29 @@ const showDetailModal = item => {
}) })
} }
</script> </script>
<style scoped>
:deep(.operator_text) .van-dropdown-menu__title {
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.07em;
color: #999999;
}
:deep(.operator_text) .van-dropdown-item {
position: absolute;
top: 80px !important;
}
:deep(.operator_text) .van-cell__title {
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.07em;
color: #999999;
}
:deep(.operator_text) .van-dropdown-menu__bar {background: transparent !important;box-shadow: none !important;}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
.histrory_container { .histrory_container {
display: flex; display: flex;
@ -241,6 +294,7 @@ const showDetailModal = item => {
line-height: normal; line-height: normal;
letter-spacing: 0.07em; letter-spacing: 0.07em;
color: #191919; color: #191919;
display : inline-flex;
} }
.btns { .btns {
display: flex; display: flex;

4
src/components/Setting/index.vue

@ -26,11 +26,11 @@
<p :class="activeTab == 5 ? 'title active' : 'title'">审计管理</p> <p :class="activeTab == 5 ? 'title active' : 'title'">审计管理</p>
<div :class="activeTab == 5 ? 'btn style-btn' : 'dis_btn'">操作</div> <div :class="activeTab == 5 ? 'btn style-btn' : 'dis_btn'">操作</div>
</div> </div>
<div class="tab_wrap" @click="changeActiveTab(6)">
<!-- <div class="tab_wrap" @click="changeActiveTab(6)">
<p class="active_line" v-show="activeTab == 6"></p> <p class="active_line" v-show="activeTab == 6"></p>
<p :class="activeTab == 6 ? 'title active' : 'title'">消毒记录管理</p> <p :class="activeTab == 6 ? 'title active' : 'title'">消毒记录管理</p>
<div :class="activeTab == 6 ? 'btn style-btn' : 'dis_btn'">操作</div> <div :class="activeTab == 6 ? 'btn style-btn' : 'dis_btn'">操作</div>
</div>
</div> -->
<div class="tab_wrap" @click="changeActiveTab(7)"> <div class="tab_wrap" @click="changeActiveTab(7)">
<p class="active_line" v-show="activeTab == 7"></p> <p class="active_line" v-show="activeTab == 7"></p>
<p :class="activeTab == 7 ? 'title active' : 'title'">历史记录</p> <p :class="activeTab == 7 ? 'title active' : 'title'">历史记录</p>

131
src/components/dialogs/ClearRecordByKeysModal.vue

@ -0,0 +1,131 @@
<template>
<div v-if="enable" class="clear_record_modal_container">
<div class="modal_content">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
fill="none"
version="1.1"
width="69"
height="69"
viewBox="0 0 69 69"
>
<g>
<path
d="M34.5,0C15.456,0,0,15.456,0,34.5C0,53.544,15.456,69,34.5,69C53.544,69,69,53.544,69,34.5C69,15.456,53.544,0,34.5,0ZM34.5,55.2C32.5335,55.2,30.981,53.613,30.981,51.681C30.981,49.7145,32.568,48.162,34.5,48.162C36.4665,48.162,38.019,49.749,38.019,51.681C38.019,53.613,36.4665,55.2,34.5,55.2ZM38.3295,15.8355L37.605,40.9515C37.5705,42.2625,36.225,43.2975,34.638,43.2975L34.086,43.2975C32.499,43.2975,31.1535,42.2625,31.119,40.9515L30.36,15.8355C30.291,13.8345,31.9125,12.144,33.9825,12.144L34.707,12.144C36.777,12.144,38.3985,13.8345,38.3295,15.8355Z"
fill="#FA1C1C"
fill-opacity="1"
/>
</g>
</svg>
<p class="tips">
<span class="red">确定要所选消毒记录吗</span>
</p>
<div class="btns">
<div class="ok style-btn" @click="handleStart">确定</div>
<div class="cancel style-btn" @click="handleCancel">取消</div>
</div>
</div>
</div>
</template>
<script setup>
import { useWebSocketStore } from '@/store'
import { cleanDisinfectionRecordByKeysJSON } from '@/mock/command'
import { ref } from 'vue'
// props
const props = defineProps({
keys : {type: Array,default: () => []}
})
// WebSocket store
const webSocketStore = useWebSocketStore()
//
const enable = ref(false);
//
defineExpose({showDialog});
function showDialog() {
enable.value = true;
}
const handleCancel = () => {
enable.value = false;
}
const handleStart = () => {
webSocketStore.sendCommandMsg(cleanDisinfectionRecordByKeysJSON(props.keys))
enable.value = false;
}
</script>
<style lang="scss" scoped>
.clear_record_modal_container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
.modal_content {
width: 476px;
height: 350px;
border-radius: 16px;
background: #ffffff;
padding: 52px 37px 55px 37px;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
.tips {
margin-top: 33px;
margin-bottom: 50px;
font-family: Source Han Sans CN;
font-size: 21px;
font-weight: normal;
letter-spacing: 0.04em;
color: #000000;
.red {
color: #fa1c1c;
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-between;
width: 362px;
.cancel {
width: 173px;
height: 68px;
border-radius: 34px;
background: #06518b;
font-family: Source Han Sans CN;
font-size: 23px;
font-weight: 350;
letter-spacing: 0em;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
.ok {
width: 173px;
height: 68px;
border-radius: 34px;
background: #1f6397;
font-family: Source Han Sans CN;
font-size: 23px;
font-weight: 350;
letter-spacing: 0em;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
</style>

8
src/main.js

@ -11,6 +11,10 @@ import {
NumberKeyboard, NumberKeyboard,
Toast, Toast,
Overlay, Overlay,
Checkbox,
CheckboxGroup,
DropdownMenu,
DropdownItem
} from 'vant' } from 'vant'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
@ -28,6 +32,10 @@ createApp(App)
.use(TimePicker) .use(TimePicker)
.use(Field) .use(Field)
.use(Overlay) .use(Overlay)
.use(Checkbox)
.use(CheckboxGroup)
.use(DropdownMenu)
.use(DropdownItem)
.use(ElementPlus) .use(ElementPlus)
.use(Toast) .use(Toast)
.use(store) .use(store)

13
src/mock/command.js

@ -223,11 +223,24 @@ export const exportDisinfectionRecordJSON = {
messageId: 'exportDisinfectionRecord', messageId: 'exportDisinfectionRecord',
} }
export const exportDisinfectionRecordByKeyListJSON = ( keys ) => ({
command: 'exportDisinfectionRecord',
messageId: 'exportDisinfectionRecord',
keys,
});
export const cleanDisinfectionRecordJSON = { export const cleanDisinfectionRecordJSON = {
command: 'cleanDisinfectionRecord', command: 'cleanDisinfectionRecord',
messageId: 'cleanDisinfectionRecord', messageId: 'cleanDisinfectionRecord',
} }
export const cleanDisinfectionRecordByKeysJSON = ( keys ) => ({
command: 'cleanDisinfectionRecord',
messageId: 'cleanDisinfectionRecord',
keys,
});
export const cleanUserBehaviorRecordJSON = { export const cleanUserBehaviorRecordJSON = {
command: 'cleanUserBehaviorRecord', command: 'cleanUserBehaviorRecord',
messageId: 'cleanUserBehaviorRecord', messageId: 'cleanUserBehaviorRecord',

Loading…
Cancel
Save