Browse Source

feat: 设备列表

master
wally 4 years ago
parent
commit
b55159de39
  1. 2
      .env.development
  2. 3
      .eslintrc.js
  3. 8
      package-lock.json
  4. 11
      package.json
  5. 37
      src/App.vue
  6. 14
      src/apis/index.js
  7. 19
      src/components/device-edit.vue
  8. 31
      src/components/search-bar.vue
  9. 4
      src/main.js
  10. 6
      src/routers/index.js
  11. 58
      src/store/device.js
  12. 11
      src/store/index.js
  13. 53
      src/store/user.js
  14. 21
      src/utils/axios.js
  15. 8
      src/views/device-create.vue
  16. 131
      src/views/device-list.vue
  17. 31
      vite.config.js

2
.env.development

@ -1 +1 @@
API_URL=http://localhost:4001
VITE_API_URL=http://localhost:4001

3
.eslintrc.js

@ -13,6 +13,9 @@ module.exports = {
'import/no-unresolved': 0,
'import/extensions': 0,
'vue/html-self-closing': 'off',
'no-unused-expressions': 'off',
'vue/no-mutating-props': 'off',
'vue/no-multiple-template-root': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-param-reassign': 'off',

8
package-lock.json

@ -4443,6 +4443,14 @@
"@vue/devtools-api": "^6.0.0-beta.18"
}
},
"vuex": {
"version": "4.0.2",
"resolved": "https://registry.nlark.com/vuex/download/vuex-4.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvuex%2Fdownload%2Fvuex-4.0.2.tgz",
"integrity": "sha1-+Jbb1b8qDpY/AMZ+m2EN50nMrMk=",
"requires": {
"@vue/devtools-api": "^6.0.0-beta.11"
}
},
"webpack-virtual-modules": {
"version": "0.4.3",
"resolved": "https://registry.nlark.com/webpack-virtual-modules/download/webpack-virtual-modules-0.4.3.tgz?cache=0&sync_timestamp=1620993523325&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwebpack-virtual-modules%2Fdownload%2Fwebpack-virtual-modules-0.4.3.tgz",

11
package.json

@ -16,12 +16,15 @@
"element-plus": "^1.1.0-beta.21",
"vue": "^3.2.16",
"vue-router": "^4.0.12",
"windicss": "^3.1.9"
"vuex": "^4.0.2",
"windicss": "^3.1.9",
"@vitejs/plugin-vue": "^1.9.3",
"vite": "^2.6.4",
"vite-plugin-windicss": "^1.4.11"
},
"devDependencies": {
"@commitlint/cli": "^13.2.1",
"@commitlint/config-angular": "^13.2.0",
"@vitejs/plugin-vue": "^1.9.3",
"commitizen": "^4.2.4",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^7.32.0",
@ -34,9 +37,7 @@
"lint-staged": "^11.2.3",
"prettier": "^2.4.1",
"unplugin-vue-components": "^0.15.6",
"vite": "^2.6.4",
"vite-plugin-linter": "^1.0.1",
"vite-plugin-windicss": "^1.4.11"
"vite-plugin-linter": "^1.0.1"
},
"browserslist": [
"Android >= 4",

37
src/App.vue

@ -1,8 +1,45 @@
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
import { useRoute } from 'vue-router';
import Navbar from 'components/navbar.vue';
import zhCn from 'element-plus/lib/locale/lang/zh-cn';
import { ElMessage } from 'element-plus';
const local = zhCn;
const store = useStore();
let timer = null;
// queryu token
const validateQuery = async () => {
const route = useRoute();
const u = computed(() => route.query.u);
if (!u) {
// urlu,
ElMessage.error('缺少用户信息参数');
} else {
// userId token
await store.dispatch('user/getTokenByUserId', u);
}
};
validateQuery();
const token = computed(() => store.getters['user/token']);
//
const getDeviceData = async () => {
if (token) {
await store.dispatch('device/getDevices');
timer && clearTimeout(timer);
timer = null;
} else {
timer = setTimeout(() => {
getDeviceData();
}, 16);
}
};
getDeviceData();
</script>
<template>

14
src/apis/index.js

@ -0,0 +1,14 @@
import http from 'utils/axios';
const apiUrl = import.meta.env.VITE_API_URL;
const users = `${apiUrl}/gateway/tall3/v3.0/users`;
const corrosion = `${apiUrl}/gateway/corrosion`;
// 根据userId 获取token
export const getToken = userId => http.get(`${users}/userId`, { params: { userId } });
// 获取设备列表
export const getDevices = () => http.get(`${corrosion}/devices`);
// 获取设备列表 完整信息
export const getDevicesAll = () => http.get(`${corrosion}/devices/all`);

19
src/components/device-edit.vue

@ -0,0 +1,19 @@
<template>
<el-dialog v-model="show" title="编辑设备信息" width="80%" :before-close="handleClose">
<span>This is a message</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="$emit('toggle-mdoal')">Cancel</el-button>
<el-button type="primary" @click="$emit('toggle-mdoal')">Confirm</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({ show: Boolean });
defineEmits(['toggle-mdoal']);
</script>

31
src/components/search-bar.vue

@ -0,0 +1,31 @@
<template>
<el-form :inline="true" :model="searchDevice" ref="searchDeviceForm">
<el-form-item label="选择站点">
<el-select v-model="searchDevice.device" placeholder="请选择站点">
<el-option label="全部" value=""></el-option>
<el-option :label="item.address" :value="item.deviceId" v-for="item in devices" :key="item.deviceId"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, computed } from 'vue';
import { useStore } from 'vuex';
const searchDevice = reactive({ device: '' });
const searchDeviceForm = ref(null); // form
const store = useStore();
const devices = computed(() => store.state.device.devices);
const onSubmit = () => {
searchDeviceForm.value.validate(valid => {
console.log(valid, { ...searchDevice });
});
};
</script>

4
src/main.js

@ -1,9 +1,11 @@
import 'virtual:windi.css';
import 'element-plus/dist/index.css';
import { createApp } from 'vue';
import App from './App.vue';
import router from './routers/index';
import store from './store/index';
const app = createApp(App);
app.use(router).mount('#app');
app.use(router).use(store).mount('#app');

6
src/routers/index.js

@ -21,6 +21,12 @@ export const routes = [
meta: { title: '设备添加' },
component: () => import('@/views/device-create.vue'),
},
{
path: '/devices',
name: 'devices',
meta: { title: '设备管理' },
component: () => import('@/views/device-list.vue'),
},
{
path: '/test',
name: 'test',

58
src/store/device.js

@ -0,0 +1,58 @@
import { getDevices, getDevicesAll } from 'apis/index';
const user = {
namespaced: true,
state: {
devices: [],
devicesAll: null,
},
getters: {},
mutations: {
/**
* 设置devices数据
* @param {*} state
* @param {array} devices
*/
setDevices(state, devices) {
state.devices = devices;
},
/**
* 设置devicesAll的数据
* @param {*} state
* @param {*} devices
*/
setDevicesAll(state, devices) {
state.devicesAll = devices;
},
},
actions: {
// 获取设备列表(站点列表)
async getDevices({ commit }) {
try {
const data = await getDevices();
commit('setDevices', data || []);
return data;
} catch (error) {
throw new Error(error);
}
},
// 获取设备列表(站点列表) 完整信息
async getDevicesAll({ commit }) {
try {
const data = await getDevicesAll();
commit('setDevicesAll', data || null);
return data;
} catch (error) {
throw new Error(error);
}
},
},
};
export default user;

11
src/store/index.js

@ -0,0 +1,11 @@
import { createStore } from 'vuex';
import device from './device';
import user from './user';
export default createStore({
modules: { user, device },
state: {},
getters: {},
mutations: {},
actions: {},
});

53
src/store/user.js

@ -0,0 +1,53 @@
import { getToken } from 'apis/index';
export default {
namespaced: true,
state: { user: null },
getters: {
token({ user }) {
if (!user) return null;
return user.token;
},
userId({ user }) {
if (!user) return null;
return user.userId;
},
},
mutations: {
/**
* 设置state.user
* @param {*} state
* @param {object|null} user 用户信息
*/
setUser(state, user) {
state.user = user;
if (user) {
localStorage.setItem('token', user.token);
localStorage.setItem('user', user);
} else {
localStorage.removeItem('token');
localStorage.removeItem('user');
}
},
},
actions: {
/**
* 根据userId获取token级user信息
* @param {*} param0
* @param {string} userId 用户id
*/
async getTokenByUserId({ commit }, userId) {
try {
const data = await getToken(userId);
commit('setUser', data || null);
return data;
} catch (error) {
throw new Error(error);
}
},
},
};

21
src/utils/axios.js

@ -1,7 +1,8 @@
import Axios from 'axios';
import { ElMessage } from 'element-plus';
import store from 'store';
const baseUrl = 'http://api.github.com';
const baseUrl = '/gateway';
const instance = Axios.create({
baseUrl,
@ -10,8 +11,13 @@ const instance = Axios.create({
// request
instance.interceptors.request.use(
response => {
return response;
config => {
// console.log(`store.getters['user/token']: `, store.getters['user/token']);
const token = store.getters['user/token'] || localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
@ -21,7 +27,14 @@ instance.interceptors.request.use(
// response
instance.interceptors.response.use(
response => {
return response;
if (response.status !== 200 || !response.data) {
return Promise.reject(response.statusText);
}
const { code, data, msg } = response.data;
if (code === 200) {
return data;
}
return Promise.reject(msg);
},
error => {
if (error.response && error.response.data) {

8
src/views/device-create.vue

@ -1,5 +1,5 @@
<template>
<el-form label-position="top" :model="data" ref="networkForm">
<el-form label-position="top" :model="data" ref="deviceCreate">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="设备ID号" prop="deviceId">
@ -159,17 +159,17 @@ const data = reactive({
remark: '', //
});
const networkForm = ref(null); // form
const deviceCreate = ref(null); // form
//
const onSubmit = () => {
networkForm.value.validate(valid => {
deviceCreate.value.validate(valid => {
console.log(valid, { ...data });
});
};
//
const onReset = () => {
networkForm.value.resetFields();
deviceCreate.value.resetFields();
};
</script>

131
src/views/device-list.vue

@ -1,26 +1,117 @@
<template>
<el-form ref="form" :model="form" :inline="true" label-width="120px">
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="Activity form">
<el-input v-model="form.desc"></el-input>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
<SearchBar />
<template v-if="devicesAll && devicesAll.data">
<el-table :data="devicesAll.data" style="width: 100%" :style="{ 'max-height': contentHeight + 'px' }">
<el-table-column type="expand">
<template #default="props">
<el-row :gutter="20" class="px-6 text-gray-400">
<el-col :span="9">链路地址{{ props.row.linkAddress }}</el-col>
<el-col :span="9">探头编号{{ props.row.probNo }}</el-col>
<el-col :span="9">设备朝向{{ props.row.deviceDirection }}</el-col>
<el-col :span="9">试样{{ props.row.simple }}</el-col>
<el-col :span="9">安装位置{{ props.row.installLocation }}</el-col>
<el-col :span="9">sim1{{ props.row.sim1 }}</el-col>
<el-col :span="18">与主站后台联调情况{{ props.row.joint }}</el-col>
<el-col :span="18">备注{{ props.row.remark }}</el-col>
</el-row>
</template>
</el-table-column>
<el-table-column label="ID" prop="deviceId" width="100" />
<el-table-column label="完整ID" prop="deviceFullId" width="150" />
<el-table-column label="地点" prop="address" width="150" />
<el-table-column label="地区" prop="area" width="120" />
<el-table-column label="联系人" prop="contact" width="100" />
<el-table-column label="联系电话" prop="phone" width="150" />
<el-table-column label="安装时间" prop="installTime" width="200" />
<el-table-column label="正式运行时间" prop="runTime" width="200" />
<el-table-column fixed="right" label="操作" width="148">
<template #default>
<el-popconfirm title="确定要删除此设备吗?" @confirm="handleDelete">
<template #reference>
<el-button type="danger" plain size="mini">删除</el-button>
</template>
</el-popconfirm>
<el-button type="primary" plain size="mini" @click="editting = true">编辑</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
background
:current-page="devicesAll.page.page"
:page-size="devicesAll.page.size"
:default-page-size="10"
:page-count="devicesAll.page.total"
class="my-3 float-right"
@size-change="onSizeChange"
@current-change="onCurrentPageChange"
@prev-click="onPrev"
@next-click="onNext"
></el-pagination>
</template>
<!-- 编辑设备信息 -->
<DeviceEdit :show="editting" @toggle-mdoal="editting = false" />
</template>
<script setup>
// import { ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { useStore } from 'vuex';
import SearchBar from 'components/search-bar.vue';
import DeviceEdit from 'components/device-edit.vue';
let timer = null;
const store = useStore();
const token = computed(() => store.getters['user/token']);
const devicesAll = computed(() => store.state.device.devicesAll);
let contentHeight = 600;
const editting = ref(false);
//
const getDevicesAllData = () => {
if (token) {
store.dispatch('device/getDevicesAll');
timer && clearTimeout(timer);
timer = null;
} else {
timer = setTimeout(() => {
getDevicesAllData();
});
}
};
getDevicesAllData();
//
onMounted(() => {
const winHeight = document.documentElement.clientHeight;
contentHeight = winHeight - 150;
});
//
const onCurrentPageChange = e => {
console.log(e);
};
//
const onSizeChange = e => {
console.log(e);
};
//
const onNext = e => {
console.log(e);
};
//
const onPrev = e => {
console.log(e);
};
// const data = {
// deviceId: '', // id
// }
//
const handleDelete = () => {
console.log('delete');
};
</script>

31
vite.config.js

@ -1,28 +1,25 @@
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import WindiCSS from 'vite-plugin-windicss';
import { defineConfig } from 'vite'
import { defineConfig } from 'vite';
import path from 'path';
import vue from '@vitejs/plugin-vue'
import vue from '@vitejs/plugin-vue';
const resolve = dir => path.join(__dirname, dir);
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
WindiCSS(),
Components({
resolvers: [ElementPlusResolver()],
}),
],
plugins: [vue(), WindiCSS(), Components({ resolvers: [ElementPlusResolver()] })],
resolve: {
alias: {
'~': __dirname,
'@': resolve('src'),
'views': resolve('src/views'),
'components': resolve('src/components'),
'assets': resolve('src/assets'),
}
}
})
views: resolve('src/views'),
components: resolve('src/components'),
assets: resolve('src/assets'),
utils: resolve('src/utils'),
store: resolve('src/store'),
apis: resolve('src/apis'),
},
},
});

Loading…
Cancel
Save