Commit 7c14ee4b by 李俊

Merge branch 'develop' of gitlab.seetatech.com:seeta-device/deviceManage into develop

2 parents 7cbcf27f 0eab7795
Pipeline #5454 passed
in 6 minutes 59 seconds
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>SeetaAIoT</title> <title>AIoT Base</title>
</head> </head>
<body> <body>
<script type="text/javascript" src="./config.js"></script> <script type="text/javascript" src="./config.js"></script>
......
...@@ -4,25 +4,6 @@ ...@@ -4,25 +4,6 @@
</div> </div>
</template> </template>
<script>
export default {
data() {
return {
formatData: [
{
label: 'test',
key: 'name',
type: 'input',
required: true,
validator: ['notEmpty', 'min2', 'max64', 'normName'],
placeholder: 'test',
},
],
}
},
}
</script>
<style> <style>
#app { #app {
font-family: PingFangSC-Regular, 微软雅黑; font-family: PingFangSC-Regular, 微软雅黑;
......
...@@ -33,6 +33,9 @@ export const deleteApp = data => axios(GET, FRONT + APPID + '/delete', data) ...@@ -33,6 +33,9 @@ export const deleteApp = data => axios(GET, FRONT + APPID + '/delete', data)
export const setApp = data => axios(GET, FRONT + APPID + '/set', data) export const setApp = data => axios(GET, FRONT + APPID + '/set', data)
export const addApp = data => axios(POST, FRONT + APPID + '/add', data) export const addApp = data => axios(POST, FRONT + APPID + '/add', data)
const ACCOUNt = '/account'
export const getAccount = data => axios(GET, FRONT + ACCOUNt + '/query', data)
const DEVICE = '/device' const DEVICE = '/device'
export const getDevice = data => axios(POST, FRONT + DEVICE + '/query_list', data) export const getDevice = data => axios(POST, FRONT + DEVICE + '/query_list', data)
export const getDeviceService = data => axios(GET, FRONT + DEVICE + '/service/query') export const getDeviceService = data => axios(GET, FRONT + DEVICE + '/service/query')
......
...@@ -62,6 +62,9 @@ Axios.interceptors.response.use(res => { ...@@ -62,6 +62,9 @@ Axios.interceptors.response.use(res => {
if (res && res.data && res.data.code !== 0) { if (res && res.data && res.data.code !== 0) {
notificationError('提示', res.data.msg) notificationError('提示', res.data.msg)
} }
if (res && res.data && res.data.code === 22 && res.data.msg === 'user do not login') {
Router.push('/login')
}
return res return res
}, error => { }, error => {
error.response && error.response.data && notificationError('提示', error.response.data.message) error.response && error.response.data && notificationError('提示', error.response.data.message)
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
</ul> </ul>
<template v-slot:reference> <template v-slot:reference>
<span class="user-info flex right"> <span class="user-info flex right">
<span v-if="userData.info">{{ userData.info.creater }}</span> <span>{{ name }}</span>
<i class="iconfont icon-mianxingxiala" <i class="iconfont icon-mianxingxiala"
:class="{ :class="{
'expand': showInfo, 'expand': showInfo,
...@@ -32,6 +32,7 @@ import { getUser, removeUser } from '@/utils/user' ...@@ -32,6 +32,7 @@ import { getUser, removeUser } from '@/utils/user'
import { logoutApi } from '@/axios' import { logoutApi } from '@/axios'
import Dialog from '@/helpers/dialog' import Dialog from '@/helpers/dialog'
import seetaPopover from '@/components/seeta-ui/seeta-popover.vue' import seetaPopover from '@/components/seeta-ui/seeta-popover.vue'
import browserStorage from '@/services/local-storage'
@Component({ @Component({
components: { components: {
...@@ -40,7 +41,9 @@ import seetaPopover from '@/components/seeta-ui/seeta-popover.vue' ...@@ -40,7 +41,9 @@ import seetaPopover from '@/components/seeta-ui/seeta-popover.vue'
}) })
export default class userInfo extends Vue { export default class userInfo extends Vue {
showInfo: boolean = false showInfo: boolean = false
get name() {
return browserStorage.getItem('nickname') || browserStorage.getItem('username')
}
get userData() { return getUser() } get userData() { return getUser() }
get shouldConfirmBeforeLeave(): boolean { get shouldConfirmBeforeLeave(): boolean {
......
...@@ -14,6 +14,18 @@ export default [ ...@@ -14,6 +14,18 @@ export default [
component: () => import('@views/register') component: () => import('@views/register')
}, },
{ {
path: '/overview',
name: 'overview',
meta: { title: '总览页面', icon: 'icon-wendanggongju', hidden: true },
component: () => import('@layouts/basicLayout'),
children: [{
path: '/overview',
name: 'overview',
meta: { title: '总览页面' },
component: () => import('@views/overview')
}]
},
{
path: '/device', path: '/device',
name: 'device', name: 'device',
meta: { title: '设备列表', icon: 'icon-shebei' }, meta: { title: '设备列表', icon: 'icon-shebei' },
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
<div class="page-nav"> <div class="page-nav">
<div class="search-fields"> <div class="search-fields">
<span class="fields">用户名:</span> <span class="fields">用户名:</span>
<st-input width="240px" class="align contents" id="align-input" v-model="userName"></st-input> <st-input width="240px" class="align contents" id="align-input" v-model="nickname" @input="getData"></st-input>
<!-- <input type="text" id="raw-input" autocomplete="off" class="align contents" :style="{borderColor: borderColor}" placeholder="请输入" @blur="getData" v-model.trim="deviceName" @keyup.enter="getData" @input="checkSearchContent"> --> <!-- <input type="text" id="raw-input" autocomplete="off" class="align contents" :style="{borderColor: borderColor}" placeholder="请输入" @blur="getData" v-model.trim="deviceName" @keyup.enter="getData" @input="checkSearchContent"> -->
<span class="fields">用户角色:</span> <span class="fields">用户角色:</span>
<st-select <st-select
v-model="userRole" v-model="role"
:options="userRoleOptions" :options="userRoleOptions"
size="small" size="small"
style="width: 240px" style="width: 240px"
...@@ -63,37 +63,47 @@ ...@@ -63,37 +63,47 @@
<div slot="body" class="popup-body"> <div slot="body" class="popup-body">
<st-form <st-form
label-width="90px" label-width="90px"
style="height: 440px"
ref="form" ref="form"
:model="form" :model="form"
:rules="rules"> :rules="rules">
<st-form-item <st-form-item :label="'账号:'" prop="username">
:label="'账号:'">
<st-input v-model="form.username" :disabled="submitType === 'edit'"></st-input> <st-input v-model="form.username" :disabled="submitType === 'edit'"></st-input>
</st-form-item> </st-form-item>
<st-form-item <st-form-item
:label="'角色:'"> :label="'昵称:'" prop="nickname">
<st-input v-model="form.role"></st-input> <st-input v-model="form.nickname"></st-input>
</st-form-item> </st-form-item>
<st-form-item <st-form-item :label="'角色:'" prop="role">
:label="'邮箱:'"> <st-select v-model="form.role" :options="userRoleOptions" clearable>
</st-select>
</st-form-item>
<st-form-item :label="'邮箱:'" prop="email">
<st-input v-model="form.email"></st-input> <st-input v-model="form.email"></st-input>
</st-form-item> </st-form-item>
<st-form-item v-if="submitType === 'create'" <st-form-item v-if="submitType === 'create'" :label="'初始密码:'" prop="passwd">
:label="'初始密码:'">
<st-input v-model="form.passwd" type="password"></st-input> <st-input v-model="form.passwd" type="password"></st-input>
</st-form-item> </st-form-item>
<st-form-item v-if="submitType === 'create'" <st-form-item v-if="submitType === 'create'" :label="'重复密码:'" prop="confirmPwd">
:label="'重复密码:'">
<st-input v-model="form.confirmPwd" type="password"></st-input> <st-input v-model="form.confirmPwd" type="password"></st-input>
</st-form-item> </st-form-item>
<st-form-item v-if="submitType === 'edit'" <st-form-item v-if="submitType === 'edit'" :label="'原密码:'" prop="passwordd">
:label="'原密码:'">
<st-input v-model="form.passwordd" type="password"></st-input> <st-input v-model="form.passwordd" type="password"></st-input>
</st-form-item> </st-form-item>
<st-form-item v-if="submitType === 'edit'" <st-form-item v-if="submitType === 'edit'" :label="'新密码:'" prop="new_passwordd">
:label="'新密码:'">
<st-input v-model="form.new_passwordd" type="password"></st-input> <st-input v-model="form.new_passwordd" type="password"></st-input>
</st-form-item> </st-form-item>
<st-form-item
:label="'备注:'">
<st-input
type="textarea"
placeholder="请输入"
v-model="form.description"
maxlength="100"
show-word-limit
>
</st-input>
</st-form-item>
</st-form> </st-form>
</div> </div>
<div slot="footer" class="popup-footer flex right"> <div slot="footer" class="popup-footer flex right">
...@@ -122,13 +132,17 @@ export default { ...@@ -122,13 +132,17 @@ export default {
} }
return { return {
// 查询字段 // 查询字段
userName: '', nickname: '',
userRole: '', role: '',
created_at: [], created_at: [],
showDialog: false, showDialog: false,
submitType: 'create', submitType: 'create',
form: {}, form: {},
userRoleOptions: [], userRoleOptions: [
{ value: 'admin', label: '管理员' },
{ value: 'operator', label: '操作员' },
{ value: 'watcher', label: '观察员' },
],
currentPage: 1, currentPage: 1,
currentSize: 10, currentSize: 10,
loadingStatus: false, loadingStatus: false,
...@@ -139,7 +153,14 @@ export default { ...@@ -139,7 +153,14 @@ export default {
}, },
{ {
label: '角色', label: '角色',
render: 'role' render: row => {
switch (row.role) {
case 'operator': return '操作员'
case 'admin': return '管理员'
case 'watcher': return '观察员'
default: return ''
}
}
}, },
{ {
label: '邮箱', label: '邮箱',
...@@ -155,7 +176,7 @@ export default { ...@@ -155,7 +176,7 @@ export default {
}, },
{ {
label: '备注', label: '备注',
render: 'desc' render: 'description'
}, },
{ {
label: '操作', label: '操作',
...@@ -167,7 +188,11 @@ export default { ...@@ -167,7 +188,11 @@ export default {
tokenList: [], tokenList: [],
total: 0, total: 0,
rules: { // 表单校验 rules: { // 表单校验
passwordConfirmation: [ username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
nickname: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
role: [{ required: true, message: '请选择角色', trigger: 'change' }],
passwd: [{ required: true, message: '请输入密码', trigger: 'blur' }],
confirmPwd: [
{ required: true, message: '请确认密码', trigger: 'blur' }, { required: true, message: '请确认密码', trigger: 'blur' },
{ validator: validatePasswordConfirmation, trigger: 'blur' } { validator: validatePasswordConfirmation, trigger: 'blur' }
] ]
...@@ -198,9 +223,8 @@ export default { ...@@ -198,9 +223,8 @@ export default {
switch (this.submitType) { switch (this.submitType) {
case 'create': case 'create':
submitForm = JSON.parse(JSON.stringify(this.form)) submitForm = JSON.parse(JSON.stringify(this.form))
delete submitForm.email
delete submitForm.confirmPwd delete submitForm.confirmPwd
submitForm.creater = 'admin' submitForm.creater = browserStorage.getItem('username')
res = await createUser(submitForm) res = await createUser(submitForm)
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
this.getData() this.getData()
...@@ -209,9 +233,8 @@ export default { ...@@ -209,9 +233,8 @@ export default {
break break
case 'edit': case 'edit':
submitForm = JSON.parse(JSON.stringify(this.form)) submitForm = JSON.parse(JSON.stringify(this.form))
delete submitForm.email
delete submitForm.confirmPwd delete submitForm.confirmPwd
submitForm.creater = 'admin' submitForm.creater = browserStorage.getItem('username')
res = await editUser(submitForm) res = await editUser(submitForm)
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
this.getData() this.getData()
...@@ -250,7 +273,7 @@ export default { ...@@ -250,7 +273,7 @@ export default {
}, },
async getData() { async getData() {
this.loadingStatus = true this.loadingStatus = true
const res = await getUsers({ pages: this.currentPage - 1, pagesize: this.currentSize }) const res = await getUsers({ pages: this.currentPage - 1, pagesize: this.currentSize, nickname: this.nickname, role: this.role, begin_date: this.created_at ? this.created_at[0] : '', end_date: this.created_at ? this.created_at[1] : '' })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
this.tokenList = res.data.data.users this.tokenList = res.data.data.users
this.total = res.data.data.total this.total = res.data.data.total
...@@ -262,6 +285,23 @@ export default { ...@@ -262,6 +285,23 @@ export default {
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
.update-dialog
::v-deep input
&::placeholder
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
color:#999999
::v-deep.el-input__inner, ::v-deep.el-textarea, ::v-deep.el-textarea__inner
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
color: #333
&::placeholder
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
color:#999999
.popup-body .popup-body
::v-deep.el-form-item ::v-deep.el-form-item
height: 32px height: 32px
...@@ -272,6 +312,12 @@ export default { ...@@ -272,6 +312,12 @@ export default {
::v-deep.el-form-item__content ::v-deep.el-form-item__content
height: 32px!important height: 32px!important
line-height: 32px!important line-height: 32px!important
::v-deep input
&::placeholder
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
color:#999999
.search-fields .search-fields
::v-deep input ::v-deep input
&::placeholder &::placeholder
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
</div> </div>
<div slot="operate" slot-scope="row"> <div slot="operate" slot-scope="row">
<span class="operate" v-if="row.ismainapp === 0" @click="setHostApp(row)">设置为主应用</span> <span class="operate" v-if="row.ismainapp === 0" @click="setHostApp(row)">设置为主应用</span>
<span class="operate" v-else @click="cancelHostApp(row)">取消设置为主应用</span> <!-- <span class="operate" v-else @click="cancelHostApp(row)">取消设置为主应用</span> -->
<span class="operate operate-delete" @click="handleDelete(row)">删除</span> <span class="operate operate-delete" v-if="row.ismainapp === 0" @click="handleDelete(row)">删除</span>
</div> </div>
</st-table> </st-table>
</div> </div>
...@@ -162,14 +162,14 @@ export default { ...@@ -162,14 +162,14 @@ export default {
} }
}, },
async setHostApp(row) { async setHostApp(row) {
const res = await setApp({ appid: row.appid, mainapp: 1, username: 'test' }) const res = await setApp({ appid: row.appid, mainapp: 1, username: browserStorage.getItem('nickname') })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
Toast.success('操作成功') Toast.success('操作成功')
this.getData() this.getData()
} }
}, },
async cancelHostApp(row) { async cancelHostApp(row) {
const res = await setApp({ appid: row.appid, mainapp: 0, username: 'test' }) const res = await setApp({ appid: row.appid, mainapp: 0, username: browserStorage.getItem('nickname') })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
Toast.success('操作成功') Toast.success('操作成功')
this.getData() this.getData()
......
<template> <template>
<div class="data-list-common flex column main-content flex-1"> <div class="data-list-common flex column main-content flex-1">
<div class="header"> <div class="header">
<span class="title">{{'数据列表 / 编辑'}}</span> <span class="title">{{'数据列表 / 编辑 / ' + $route.query.name}}</span>
</div> </div>
<div class="page-content" @click="handleClick"> <div class="page-content" @click="handleClick">
<div class="content-header"> <div class="content-header">
<st-button type="primary" @click="addTableData"> <st-button type="primary" @click="addTableData">
<i class="iconfont icon-tianjia"></i><span class="text">{{'插入数据'}}</span></st-button> <i class="iconfont icon-tianjia"></i><span class="text">{{'插入数据'}}</span></st-button>
<div class="search-box"> <div class="search-box">
<el-checkbox v-model="isBase64">Base64</el-checkbox> <!-- <el-checkbox v-model="isBase64">Base64</el-checkbox> -->
<st-select <!-- <st-select
v-model="inputVal" v-model="inputVal"
:options="orderOptions" :options="orderOptions"
size="small" size="small"
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
clearable clearable
placeholder="序号" placeholder="序号"
> >
</st-select> </st-select> -->
<div class="search"> <div class="search">
<input type="text" class="search-input" placeholder="请输入搜索内容" v-model="inputVal"> <input type="text" class="search-input" placeholder="请输入搜索内容" v-model="content" @input="getData">
<i class="el-input__icon el-icon-search"></i> <i class="el-input__icon el-icon-search"></i>
</div> </div>
</div> </div>
...@@ -95,7 +95,7 @@ import { base64ToString, stringToBase64, isASCII } from '@/utils/typeConversion' ...@@ -95,7 +95,7 @@ import { base64ToString, stringToBase64, isASCII } from '@/utils/typeConversion'
export default { export default {
data() { data() {
return { return {
inputVal: '', content: '',
isBase64: false, isBase64: false,
loadingStatus: false, loadingStatus: false,
totalColumns: Number(this.$route.query.columns), totalColumns: Number(this.$route.query.columns),
...@@ -134,7 +134,7 @@ export default { ...@@ -134,7 +134,7 @@ export default {
methods: { methods: {
async getData() { async getData() {
this.loadingStatus = true this.loadingStatus = true
const res = await getData({ name: this.$route.query.name, pages: this.currentPage - 1, pagesize: this.currentSize }) const res = await getData({ name: this.$route.query.name, pages: this.currentPage - 1, pagesize: this.currentSize, content: this.content })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
this.tableData = res.data.table.data.map(item => { this.tableData = res.data.table.data.map(item => {
item.binary = item.binary.map(base64 => { item.binary = item.binary.map(base64 => {
...@@ -189,7 +189,7 @@ export default { ...@@ -189,7 +189,7 @@ export default {
binaryItem.push(ite.value) binaryItem.push(ite.value)
} }
}) })
if (binaryItem.length === Number(this.$route.query.columns)) { if (binaryItem.length === this.totalColumns) {
binaryData.push(binaryItem) binaryData.push(binaryItem)
} }
}) })
...@@ -209,7 +209,7 @@ export default { ...@@ -209,7 +209,7 @@ export default {
}, },
addTableData() { addTableData() {
const binary = [] const binary = []
for (let i = 0; i < Number(this.$route.query.columns); i++) { for (let i = 0; i < this.totalColumns; i++) {
binary.push({ type: '', value: '' }) binary.push({ type: '', value: '' })
} }
this.insertData.push({ this.insertData.push({
...@@ -252,7 +252,8 @@ export default { ...@@ -252,7 +252,8 @@ export default {
if (this.agoCell !== cell) { if (this.agoCell !== cell) {
this.clearCell(this.agoCell) this.clearCell(this.agoCell)
} }
this.columnIndex = Number(column.label.substring(1)) // 编辑行时扩展列
if (!row.id) this.columnIndex = Number(column.label.substring(1))
cell.getElementsByClassName('el-select')[0] && cell.getElementsByClassName('el-select')[0].classList.remove('none-display') cell.getElementsByClassName('el-select')[0] && cell.getElementsByClassName('el-select')[0].classList.remove('none-display')
if (cell.getElementsByTagName('input')[0] && cell.getElementsByTagName('input')[1]) { if (cell.getElementsByTagName('input')[0] && cell.getElementsByTagName('input')[1]) {
cell.getElementsByTagName('input')[0].classList.add('write') cell.getElementsByTagName('input')[0].classList.add('write')
...@@ -386,6 +387,7 @@ export default { ...@@ -386,6 +387,7 @@ export default {
width: 240px width: 240px
height: 32px height: 32px
position: relative position: relative
margin-left: 10px
.search-input .search-input
width: 100% width: 100%
padding-right: 35px padding-right: 35px
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<st-button type="primary" id="btn" @click="showDialog = true"> <st-button type="primary" id="btn" @click="showDialog = true">
<i class="iconfont icon-tianjia"></i><span class="text">{{'创建数据表'}}</span></st-button> <i class="iconfont icon-tianjia"></i><span class="text">{{'创建数据表'}}</span></st-button>
<div class="search"> <div class="search">
<input type="text" class="search-input" placeholder="请输入搜索内容" v-model="inputVal"> <input type="text" class="search-input" placeholder="请输入搜索内容" v-model="inputVal" @input="getData">
<i class="el-input__icon el-icon-search"></i> <i class="el-input__icon el-icon-search"></i>
</div> </div>
</div> </div>
...@@ -87,7 +87,7 @@ export default { ...@@ -87,7 +87,7 @@ export default {
render: 'rows' render: 'rows'
}, },
{ {
label: '容量', label: '容量(kb)',
render: 'storage' render: 'storage'
}, },
{ {
...@@ -129,7 +129,7 @@ export default { ...@@ -129,7 +129,7 @@ export default {
methods: { methods: {
async getData() { async getData() {
this.loadingStatus = true this.loadingStatus = true
const res = await getTable({ pages: this.currentPage - 1, pagesize: this.currentSize }) const res = await getTable({ pages: this.currentPage - 1, pagesize: this.currentSize, name: this.inputVal })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
this.tokenList = res.data.data.tables.map((item, index) => { this.tokenList = res.data.data.tables.map((item, index) => {
item.order = index + 1 + (this.currentPage - 1) * this.currentSize item.order = index + 1 + (this.currentPage - 1) * this.currentSize
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<st-form-item <st-form-item
:label="'模板类型'+':'" :label="'模板类型'+':'"
prop="type"> prop="type">
<st-input v-model="form.type"></st-input> <st-input v-model="form.type" :disabled="$route.query.level === '2'"></st-input>
</st-form-item> </st-form-item>
<st-form-item <st-form-item
:label="'基础模板'+':'" :label="'基础模板'+':'"
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
clearable clearable
> >
</st-select> --> </st-select> -->
<el-select v-model="form.base" placeholder="请选择" style="width: 400px;height: 32px;line-height: 32px"> <el-select v-model="form.base" placeholder="请选择" style="width: 400px;height: 32px;line-height: 32px" @change="handleSelectBase">
<el-option <el-option
v-for="item in baseOptions" v-for="item in baseOptions"
:key="item.name" :key="item.name"
...@@ -65,12 +65,12 @@ ...@@ -65,12 +65,12 @@
style="width: 100%"> style="width: 100%">
<el-table-column label="字段"> <el-table-column label="字段">
<template slot-scope="scope"> <template slot-scope="scope">
<input type="text" v-model="scope.row.field" @blur="handleBlur" placeholder="请输入"> <input type="text" v-model="scope.row.field" @blur="handleBlur" placeholder="请输入" :disabled="Boolean(scope.row.level)">
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="类型"> <el-table-column label="类型">
<template slot-scope="scope"> <template slot-scope="scope">
<pack-select v-model="scope.row.type" placeholder="请选择" @blur="handleBlur" @visible-change="handleVisibleChange" @change="handleChange(scope.row)"> <pack-select v-model="scope.row.type" placeholder="请选择" @blur="handleBlur" @visible-change="handleVisibleChange" @change="handleChange(scope.row)" :disabled="Boolean(scope.row.level)">
<el-option <el-option
v-for="item in typeOptions" v-for="item in typeOptions"
:key="item.value" :key="item.value"
...@@ -87,8 +87,8 @@ ...@@ -87,8 +87,8 @@
<span class="upload-btn" v-if="!scope.row.value">Select File</span> <span class="upload-btn" v-if="!scope.row.value">Select File</span>
<input type="file" @blur="handleBlur" @change="(event) => handleUpload(event, scope.row)" class="input-btn" v-if="!scope.row.value"> <input type="file" @blur="handleBlur" @change="(event) => handleUpload(event, scope.row)" class="input-btn" v-if="!scope.row.value">
<span v-if="scope.row.value"> <span v-if="scope.row.value">
<span style="float: left;margin-right: 10px">{{calculateByte(scope.row.value)}}字节</span> <span style="float: left;margin-right: 10px" @click="scope.row.value = ''">{{calculateByte(scope.row.value)}}字节</span>
<el-image style="width: 42px; height: 28px;overflow: visible" :src="scope.row.value" fit="fit"> <el-image style="width: 42px; height: 28px;overflow: visible" :src="scope.row.value" fit="fit" :preview-src-list="[scope.row.value]">
<div slot="error" style="width: 80px; height: 28px;overflow: visible">(不可预览)</div> <div slot="error" style="width: 80px; height: 28px;overflow: visible">(不可预览)</div>
</el-image> </el-image>
</span> </span>
...@@ -107,7 +107,9 @@ ...@@ -107,7 +107,9 @@
</el-table-column> </el-table-column>
<el-table-column label="操作"> <el-table-column label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<span @click="handleDelete(scope.$index)" class="delete-btn">删除</span> <span @click="handleHidden(scope.row)" class="delete-btn" style="color: #E6A23C" v-if="scope.row.level">隐藏</span>
<span @click="handleReturnBack(scope.row, scope.$index)" style="color: #409EFF" class="delete-btn" v-if="scope.row.level && scope.row.value != originalData[scope.$index].value">撤回</span>
<span @click="handleDelete(scope.$index)" class="delete-btn" v-if="!scope.row.level">删除</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -126,7 +128,7 @@ ...@@ -126,7 +128,7 @@
</template> </template>
<script> <script>
import { createParameter, getTable, getParameter } from '@/axios' import { createParameter, getTable, getParameter, detailParameter } from '@/axios'
import { fileToBase64 } from '@/utils/typeConversion' import { fileToBase64 } from '@/utils/typeConversion'
import { calculateByte } from '@/utils/system' import { calculateByte } from '@/utils/system'
import Dialog from '@/helpers/dialog' import Dialog from '@/helpers/dialog'
...@@ -151,6 +153,7 @@ export default { ...@@ -151,6 +153,7 @@ export default {
tableOptions: [], tableOptions: [],
baseOptions: [], baseOptions: [],
tableData: [], tableData: [],
originalData: [],
flexHeight: 0, flexHeight: 0,
currentRow: '' currentRow: ''
} }
...@@ -183,8 +186,37 @@ export default { ...@@ -183,8 +186,37 @@ export default {
this.baseOptions = res.data.parameters.datas this.baseOptions = res.data.parameters.datas
} }
}, },
async handleSelectBase(value) {
const res = await detailParameter({ name: value })
if (res && res.data && res.data.code === 0) {
this.form.type = res.data.type
this.tableData = []
const binaryObj = res.data.parameters.binary
const scalarsObj = res.data.parameters.scalars
const tableObj = res.data.parameters.table
for (const key in binaryObj) {
this.tableData.push({ field: key, type: 'blob', value: binaryObj[key], level: 1 })
}
for (const key in scalarsObj) {
this.tableData.push({ field: key, type: typeof scalarsObj[key], value: scalarsObj[key], level: 1 })
}
for (const key in tableObj) {
this.tableData.push({ field: key, type: 'table', value: tableObj[key], level: 1 })
}
this.originalData = JSON.parse(JSON.stringify(this.tableData))
}
},
async save() { async save() {
const tableData = this.tableData.filter(item => item.field && item.value) const tableDataTemp = this.tableData.filter(item => item.field !== '' && item.type !== '' && item.value !== '')
// 最终提交的数据字段名不重复
const temp = []
const tableData = []
for (let i = 0; i < tableDataTemp.length; i++) {
if (!temp.includes(tableDataTemp[i].field)) {
temp.push(tableDataTemp[i].field)
tableData.push(tableDataTemp[i])
}
}
const scalarsArr = tableData.filter(item => item.type === 'string' || item.type === 'number') const scalarsArr = tableData.filter(item => item.type === 'string' || item.type === 'number')
const binaryArr = tableData.filter(item => item.type === 'blob') const binaryArr = tableData.filter(item => item.type === 'blob')
const tableArr = tableData.filter(item => item.type === 'table') const tableArr = tableData.filter(item => item.type === 'table')
...@@ -192,9 +224,6 @@ export default { ...@@ -192,9 +224,6 @@ export default {
const binaryObj = {} const binaryObj = {}
const tableObj = {} const tableObj = {}
for (let i = 0; i < scalarsArr.length; i++) { for (let i = 0; i < scalarsArr.length; i++) {
scalarsObj[scalarsArr[i].field] = scalarsArr[i].value
}
for (let j = 0; j < binaryArr.length; j++) {
binaryObj[binaryArr[j].field] = binaryArr[j].value binaryObj[binaryArr[j].field] = binaryArr[j].value
} }
for (let k = 0; k < tableArr.length; k++) { for (let k = 0; k < tableArr.length; k++) {
...@@ -210,11 +239,13 @@ export default { ...@@ -210,11 +239,13 @@ export default {
}) })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
Toast.success('操作成功') Toast.success('操作成功')
this.$router.push({ path: '/params' }) // this.$router.push({ path: '/params' })
} }
}, },
cancel() { cancel() {
this.$router.push({ path: '/params' }) // this.$router.push({ path: '/params' })
this.form = {}
this.tableData = []
}, },
async handleUpload(event, row) { async handleUpload(event, row) {
row.value = await fileToBase64(event.target.files[0]) row.value = await fileToBase64(event.target.files[0])
...@@ -222,8 +253,17 @@ export default { ...@@ -222,8 +253,17 @@ export default {
insertTableData() { insertTableData() {
this.tableData.push({ field: '', type: '', value: '' }) this.tableData.push({ field: '', type: '', value: '' })
}, },
handleReturnBack(row, index) {
row.value = JSON.parse(JSON.stringify(this.originalData[index])).value
this.$forceUpdate()
},
handleHidden(row) {
row.value = null
this.$forceUpdate()
},
handleDelete(index) { handleDelete(index) {
this.tableData.splice(index, 1) this.tableData.splice(index, 1)
this.$forceUpdate()
}, },
setFlexHeight() { setFlexHeight() {
const ele = document.getElementsByClassName('flex-item') && document.getElementsByClassName('flex-item')[0] const ele = document.getElementsByClassName('flex-item') && document.getElementsByClassName('flex-item')[0]
...@@ -242,6 +282,7 @@ export default { ...@@ -242,6 +282,7 @@ export default {
event.target && event.target.classList && event.target.classList.remove('write') event.target && event.target.classList && event.target.classList.remove('write')
}, },
cellClick(row, column, cell, event) { cellClick(row, column, cell, event) {
if (row.level && (column.label === '字段' || column.label === '类型')) return
if (cell.getElementsByTagName('input')[0]) { if (cell.getElementsByTagName('input')[0]) {
cell.getElementsByTagName('input')[0].classList.add('write') cell.getElementsByTagName('input')[0].classList.add('write')
cell.getElementsByTagName('input')[0].focus() cell.getElementsByTagName('input')[0].focus()
......
...@@ -26,20 +26,22 @@ ...@@ -26,20 +26,22 @@
:options="definitions" :options="definitions"
:pagination="false" :pagination="false"
:data="{ :data="{
list: tokenList, list: tableData,
total: total, total: total,
}" }"
:outerLoading="loadingStatus"> :outerLoading="loadingStatus">
<div slot="value" slot-scope="row"> <div slot="value" slot-scope="row">
<span v-if="row.value === null" class="cell-null">null</span>
<span v-else>
<span v-if="row.type === 'number' || row.type === 'string'">{{row.value}}</span> <span v-if="row.type === 'number' || row.type === 'string'">{{row.value}}</span>
<span v-if="row.type === 'blob'" style="line-height: 28px"> <span v-if="row.type === 'blob'" style="line-height: 28px">
<!-- TODO --> <span style="float: left;margin-right: 10px">{{parseInt(calculateByte(row.value))}}&nbsp;字节</span>
<span style="float: left;margin-right: 10px">{{calculateByte(row.value)}}字节</span> <el-image style="width: 42px; height: 28px;overflow: visible" :src="row.value" fit="fit" :preview-src-list="[row.value]">
<el-image style="width: 42px; height: 28px;overflow: visible" :src="row.value" fit="fit">
<div slot="error" style="width: 80px; height: 28px;overflow: visible">(不可预览)</div> <div slot="error" style="width: 80px; height: 28px;overflow: visible">(不可预览)</div>
</el-image> </el-image>
</span> </span>
<span v-if="row.type === 'table'" style="color: #409EFF; cursor: pointer" @click="$router.push({ path: '/data' })">{{row.value}}</span> <span v-if="row.type === 'table'" style="color: #409EFF; cursor: pointer" @click="handleToTableDetail(row.value)">{{row.value}}</span>
</span>
</div> </div>
</st-table> </st-table>
</st-form-item> </st-form-item>
...@@ -49,7 +51,7 @@ ...@@ -49,7 +51,7 @@
</template> </template>
<script> <script>
import { detailParameter } from '@/axios' import { detailParameter, getTable } from '@/axios'
import { calculateByte } from '@/utils/system' import { calculateByte } from '@/utils/system'
export default { export default {
data() { data() {
...@@ -71,7 +73,8 @@ export default { ...@@ -71,7 +73,8 @@ export default {
slotName: 'value' slotName: 'value'
} }
], ],
tokenList: [], baseData: [],
tableData: [],
total: 0 total: 0
} }
}, },
...@@ -79,24 +82,69 @@ export default { ...@@ -79,24 +82,69 @@ export default {
this.loadingStatus = true this.loadingStatus = true
const res = await detailParameter({ name: this.$route.query.name }) const res = await detailParameter({ name: this.$route.query.name })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
let binaryObj = {}
let scalarsObj = {}
let tableObj = {}
let binaryObj1 = {}
let scalarsObj1 = {}
let tableObj1 = {}
if (res.data.base) {
const base = await detailParameter({ name: res.data.base })
if (base && base.data && base.data.code === 0) {
binaryObj1 = base.data.parameters.binary
scalarsObj1 = base.data.parameters.scalars
tableObj1 = base.data.parameters.table
this.baseObj = Object.assign(JSON.parse(JSON.stringify(binaryObj1)), JSON.parse(JSON.stringify(scalarsObj1)), JSON.parse(JSON.stringify(tableObj1)))
for (const key in binaryObj1) {
this.baseData.push({ field: key, type: 'blob', value: binaryObj1[key], level: 1 })
}
for (const key in scalarsObj1) {
this.baseData.push({ field: key, type: typeof scalarsObj1[key], value: scalarsObj1[key], level: 1 })
}
for (const key in tableObj1) {
this.baseData.push({ field: key, type: 'table', value: tableObj1[key], level: 1 })
}
}
}
this.form = res.data this.form = res.data
const binaryObj = res.data.parameters.binary binaryObj = Object.assign(JSON.parse(JSON.stringify(binaryObj1)), res.data.parameters.binary)
const scalarsObj = res.data.parameters.scalars scalarsObj = Object.assign(JSON.parse(JSON.stringify(scalarsObj1)), res.data.parameters.scalars)
const tableObj = res.data.parameters.table tableObj = Object.assign(JSON.parse(JSON.stringify(tableObj1)), res.data.parameters.table)
const frontData = []
const endData = []
for (const key in binaryObj) { for (const key in binaryObj) {
this.tokenList.push({ field: key, type: 'blob', value: binaryObj[key] }) if (binaryObj1[key]) {
frontData.push({ field: key, type: 'blob', value: binaryObj[key], level: 1 })
} else {
endData.push({ field: key, type: 'blob', value: binaryObj[key] })
}
} }
for (const key in scalarsObj) { for (const key in scalarsObj) {
this.tokenList.push({ field: key, type: typeof scalarsObj[key], value: scalarsObj[key] }) if (scalarsObj1[key]) {
frontData.push({ field: key, type: typeof scalarsObj[key], value: scalarsObj[key], level: 1 })
} else {
endData.push({ field: key, type: typeof scalarsObj[key], value: scalarsObj[key] })
}
} }
for (const key in tableObj) { for (const key in tableObj) {
this.tokenList.push({ field: key, type: 'table', value: tableObj[key] }) if (tableObj1[key]) {
frontData.push({ field: key, type: 'table', value: tableObj[key], level: 1 })
} else {
endData.push({ field: key, type: 'table', value: tableObj[key] })
}
} }
this.tableData = frontData.concat(endData)
} }
this.loadingStatus = false this.loadingStatus = false
}, },
methods: { methods: {
calculateByte: base64 => calculateByte(base64), calculateByte: base64 => calculateByte(base64),
async handleToTableDetail(name) {
const res = await getTable({ pages: 0, pagesize: 1, name: name })
if (res && res.data && res.data.code === 0) {
this.$router.push({ path: '/data/edit', query: { name: name, columns: res.data.data && res.data.data.tables.length && res.data.data.tables[0].columns } })
}
}
} }
} }
</script> </script>
...@@ -121,4 +169,12 @@ export default { ...@@ -121,4 +169,12 @@ export default {
::v-deep .cell ::v-deep .cell
height: 28px height: 28px
line-height: 28px!important line-height: 28px!important
.cell-null
display: inline-block
height: 26px
line-height: 26px
padding: 0 10px
color: #fff
background: #ccc
border-radius: 4px
</style> </style>
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<st-form-item <st-form-item
:label="'模板类型'+':'" :label="'模板类型'+':'"
prop="type"> prop="type">
<st-input v-model="form.type"></st-input> <st-input v-model="form.type" :disabled="$route.query.level === '2'"></st-input>
</st-form-item> </st-form-item>
<st-form-item <st-form-item
:label="'基础模板'+':'" :label="'基础模板'+':'"
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
clearable clearable
> >
</st-select> --> </st-select> -->
<el-select v-model="form.base" placeholder="请选择" style="width: 400px;height: 32px;line-height: 32px"> <el-select v-model="form.base" placeholder="请选择" style="width: 400px;height: 32px;line-height: 32px" :disabled="true">
<el-option <el-option
v-for="item in baseOptions" v-for="item in baseOptions"
:key="item.name" :key="item.name"
...@@ -66,12 +66,12 @@ ...@@ -66,12 +66,12 @@
v-loading="loadingStatus"> v-loading="loadingStatus">
<el-table-column label="字段"> <el-table-column label="字段">
<template slot-scope="scope"> <template slot-scope="scope">
<input type="text" v-model="scope.row.field" @blur="handleBlur" placeholder="请输入"> <input type="text" v-model="scope.row.field" @blur="handleBlur" placeholder="请输入" :disabled="Boolean(scope.row.level)">
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="类型"> <el-table-column label="类型">
<template slot-scope="scope"> <template slot-scope="scope">
<pack-select v-model="scope.row.type" placeholder="请选择" @blur="handleBlur" @visible-change="handleVisibleChange" @change="handleChange(scope.row)"> <pack-select v-model="scope.row.type" placeholder="请选择" @blur="handleBlur" @visible-change="handleVisibleChange" @change="handleChange(scope.row)" :disabled="Boolean(scope.row.level)">
<el-option <el-option
v-for="item in typeOptions" v-for="item in typeOptions"
:key="item.value" :key="item.value"
...@@ -83,16 +83,21 @@ ...@@ -83,16 +83,21 @@
</el-table-column> </el-table-column>
<el-table-column label="值"> <el-table-column label="值">
<template slot-scope="scope"> <template slot-scope="scope">
<input v-if="scope.row.type === 'string' || scope.row.type === 'number'" type="text" v-model="scope.row.value" @blur="handleBlur" placeholder="请输入"> <!-- string number -->
<input v-if="scope.row.type === 'string' || scope.row.type === 'number'" type="text" v-model="scope.row.value" @blur="handleBlur" placeholder="请输入" :style="{color: scope.row.value != freezeData[scope.$index].value ? '#F56C6C' : ''}">
<!-- blob -->
<div class="btn-box" v-if="scope.row.type === 'blob'"> <div class="btn-box" v-if="scope.row.type === 'blob'">
<span class="upload-btn" v-if="!scope.row.value">Select File</span> <span class="upload-btn" v-if="!scope.row.value">Select File</span>
<input type="file" @blur="handleBlur" @change="(event) => handleUpload(event, scope.row)" class="input-btn" v-if="!scope.row.value"> <input type="file" @blur="handleBlur" @change="(event) => handleUpload(event, scope.row)" class="input-btn" v-if="!scope.row.value">
<span v-if="scope.row.value" style="float: left;margin-right: 10px">{{calculateByte(scope.row.value)}}字节</span> <span v-if="scope.row.value" :style="{color: scope.row.value != freezeData[scope.$index].value ? '#F56C6C' : ''}">
<el-image v-if="scope.row.value" style="width: 42px; height: 28px;overflow: visible" :src="scope.row.value" fit="fit"> <span style="float: left;margin-right: 10px" @click="scope.row.value = ''">{{parseInt(calculateByte(scope.row.value))}}&nbsp;字节</span>
<el-image style="width: 42px; height: 28px;overflow: visible" :src="scope.row.value" fit="fit" :preview-src-list="[scope.row.value]">
<div slot="error" style="width: 80px; height: 28px;overflow: visible">(不可预览)</div> <div slot="error" style="width: 80px; height: 28px;overflow: visible">(不可预览)</div>
</el-image> </el-image>
</span>
</div> </div>
<div v-if="scope.row.type === 'table'"> <!-- table -->
<div v-if="scope.row.type === 'table'" :class="{updated: scope.row.value != freezeData[scope.$index].value ? true : false}">
<pack-select v-model="scope.row.value" placeholder="请选择" @blur="handleBlur" @visible-change="handleVisibleChange"> <pack-select v-model="scope.row.value" placeholder="请选择" @blur="handleBlur" @visible-change="handleVisibleChange">
<el-option <el-option
v-for="item in tableOptions" v-for="item in tableOptions"
...@@ -106,7 +111,9 @@ ...@@ -106,7 +111,9 @@
</el-table-column> </el-table-column>
<el-table-column label="操作"> <el-table-column label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<span @click="handleDelete(scope.$index)" class="delete-btn">删除</span> <span @click="handleHidden(scope.row)" class="delete-btn" style="color: #E6A23C" v-if="scope.row.level">隐藏</span>
<span @click="handleReturnBack(scope.row, scope.$index)" style="color: #409EFF" class="delete-btn" v-if="scope.row.level && baseObj[scope.row.field] != scope.row.value">撤回</span>
<span @click="handleDelete(scope.$index)" class="delete-btn" v-if="!scope.row.level">删除</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -152,6 +159,10 @@ export default { ...@@ -152,6 +159,10 @@ export default {
tableOptions: [], tableOptions: [],
baseOptions: [], baseOptions: [],
tableData: [], tableData: [],
freezeData: [],
baseData: [],
tableObj: {},
baseObj: {},
flexHeight: 0, flexHeight: 0,
currentRow: '' currentRow: ''
} }
...@@ -189,27 +200,89 @@ export default { ...@@ -189,27 +200,89 @@ export default {
this.loadingStatus = true this.loadingStatus = true
const res = await detailParameter({ name: this.$route.query.name }) const res = await detailParameter({ name: this.$route.query.name })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
let binaryObj = {}
let scalarsObj = {}
let tableObj = {}
let binaryObj1 = {}
let scalarsObj1 = {}
let tableObj1 = {}
if (this.$route.query.level === '2' && res.data.base) {
const base = await detailParameter({ name: res.data.base })
if (base && base.data && base.data.code === 0) {
binaryObj1 = base.data.parameters.binary
scalarsObj1 = base.data.parameters.scalars
tableObj1 = base.data.parameters.table
this.baseObj = Object.assign(JSON.parse(JSON.stringify(binaryObj1)), JSON.parse(JSON.stringify(scalarsObj1)), JSON.parse(JSON.stringify(tableObj1)))
for (const key in binaryObj1) {
this.baseData.push({ field: key, type: 'blob', value: binaryObj1[key], level: 1 })
}
for (const key in scalarsObj1) {
this.baseData.push({ field: key, type: typeof scalarsObj1[key], value: scalarsObj1[key], level: 1 })
}
for (const key in tableObj1) {
this.baseData.push({ field: key, type: 'table', value: tableObj1[key], level: 1 })
}
}
}
this.form = res.data this.form = res.data
const binaryObj = res.data.parameters.binary binaryObj = Object.assign(JSON.parse(JSON.stringify(binaryObj1)), res.data.parameters.binary)
const scalarsObj = res.data.parameters.scalars scalarsObj = Object.assign(JSON.parse(JSON.stringify(scalarsObj1)), res.data.parameters.scalars)
const tableObj = res.data.parameters.table tableObj = Object.assign(JSON.parse(JSON.stringify(tableObj1)), res.data.parameters.table)
const frontData = []
const endData = []
for (const key in binaryObj) { for (const key in binaryObj) {
this.tableData.push({ field: key, type: 'blob', value: binaryObj[key] }) if (binaryObj1[key]) {
frontData.push({ field: key, type: 'blob', value: binaryObj[key], level: 1 })
} else {
endData.push({ field: key, type: 'blob', value: binaryObj[key] })
}
} }
for (const key in scalarsObj) { for (const key in scalarsObj) {
this.tableData.push({ field: key, type: typeof scalarsObj[key], value: scalarsObj[key] }) if (scalarsObj1[key]) {
frontData.push({ field: key, type: typeof scalarsObj1[key], value: scalarsObj[key], level: 1 })
} else {
endData.push({ field: key, type: typeof scalarsObj[key], value: scalarsObj[key] })
}
} }
for (const key in tableObj) { for (const key in tableObj) {
this.tableData.push({ field: key, type: 'table', value: tableObj[key] }) if (tableObj1[key]) {
frontData.push({ field: key, type: 'table', value: tableObj[key], level: 1 })
} else {
endData.push({ field: key, type: 'table', value: tableObj[key] })
}
} }
this.tableData = frontData.concat(endData)
this.freezeData = Object.freeze(JSON.parse(JSON.stringify(this.tableData)))
} }
this.loadingStatus = false this.loadingStatus = false
}, },
cancel() { cancel() {
this.$router.push({ path: '/params' }) this.getData()
// this.$router.push({ path: '/params' })
},
handleHidden(row) {
row.value = null
this.$forceUpdate()
},
handleReturnBack(row, index) {
row.value = JSON.parse(JSON.stringify(this.baseData[index])).value
this.$forceUpdate()
},
handleDelete(index) {
this.tableData.splice(index, 1)
this.$forceUpdate()
}, },
async save() { async save() {
const tableData = this.tableData.filter(item => item.field && item.value) const tableDataTemp = this.tableData.filter(item => item.field !== '' && item.type !== '' && item.value !== '')
// 最终提交的数据字段名不重复
const temp = []
const tableData = []
for (let i = 0; i < tableDataTemp.length; i++) {
if (!temp.includes(tableDataTemp[i].field)) {
temp.push(tableDataTemp[i].field)
tableData.push(tableDataTemp[i])
}
}
const scalarsArr = tableData.filter(item => item.type === 'string' || item.type === 'number') const scalarsArr = tableData.filter(item => item.type === 'string' || item.type === 'number')
const binaryArr = tableData.filter(item => item.type === 'blob') const binaryArr = tableData.filter(item => item.type === 'blob')
const tableArr = tableData.filter(item => item.type === 'table') const tableArr = tableData.filter(item => item.type === 'table')
...@@ -217,7 +290,7 @@ export default { ...@@ -217,7 +290,7 @@ export default {
const binaryObj = {} const binaryObj = {}
const tableObj = {} const tableObj = {}
for (let i = 0; i < scalarsArr.length; i++) { for (let i = 0; i < scalarsArr.length; i++) {
scalarsObj[scalarsArr[i].field] = scalarsArr[i].value scalarsObj[scalarsArr[i].field] = scalarsArr[i].value === null ? null : (scalarsArr[i].type === 'number' ? Number(scalarsArr[i].value) : String(scalarsArr[i].value))
} }
for (let j = 0; j < binaryArr.length; j++) { for (let j = 0; j < binaryArr.length; j++) {
binaryObj[binaryArr[j].field] = binaryArr[j].value binaryObj[binaryArr[j].field] = binaryArr[j].value
...@@ -235,7 +308,8 @@ export default { ...@@ -235,7 +308,8 @@ export default {
}) })
if (res && res.data && res.data.code === 0) { if (res && res.data && res.data.code === 0) {
Toast.success('操作成功') Toast.success('操作成功')
this.$router.push({ path: '/params' }) this.getData()
// this.$router.push({ path: '/params' })
} }
}, },
async handleUpload(event, row) { async handleUpload(event, row) {
...@@ -244,9 +318,6 @@ export default { ...@@ -244,9 +318,6 @@ export default {
insertTableData() { insertTableData() {
this.tableData.push({ field: '', type: '', value: '' }) this.tableData.push({ field: '', type: '', value: '' })
}, },
handleDelete(index) {
this.tableData.splice(index, 1)
},
handleChange(row) { handleChange(row) {
row.value = '' row.value = ''
}, },
...@@ -264,6 +335,7 @@ export default { ...@@ -264,6 +335,7 @@ export default {
event.target && event.target.classList && event.target.classList.remove('write') event.target && event.target.classList && event.target.classList.remove('write')
}, },
cellClick(row, column, cell, event) { cellClick(row, column, cell, event) {
if (row.level && (column.label === '字段' || column.label === '类型')) return
if (cell.getElementsByTagName('input')[0]) { if (cell.getElementsByTagName('input')[0]) {
cell.getElementsByTagName('input')[0].classList.add('write') cell.getElementsByTagName('input')[0].classList.add('write')
cell.getElementsByTagName('input')[0].focus() cell.getElementsByTagName('input')[0].focus()
...@@ -339,9 +411,9 @@ export default { ...@@ -339,9 +411,9 @@ export default {
color: #666 color: #666
background: rgba(0, 0, 0, 0) background: rgba(0, 0, 0, 0)
height: 32px height: 32px
color: #F56C6C !important
::v-deep thead ::v-deep thead
font-size: 14px font-size: 14px
font-family: PingFang-SC-Bold, PingFang-SC
font-weight: bold font-weight: bold
color: #333333 color: #333333
line-height: 20px line-height: 20px
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<st-button type="primary" @click="$router.push({ path: '/params/add', query: { level: 1 } })"> <st-button type="primary" @click="$router.push({ path: '/params/add', query: { level: 1 } })">
<i class="iconfont icon-tianjia"></i><span class="text">{{'添加'}}</span></st-button> <i class="iconfont icon-tianjia"></i><span class="text">{{'添加'}}</span></st-button>
<div class="search"> <div class="search">
<input type="text" class="search-input" placeholder="请输入搜索内容" v-model="oneVal"> <input type="text" class="search-input" placeholder="请输入搜索内容" v-model="oneVal" @input="getOneData">
<i class="el-input__icon el-icon-search"></i> <i class="el-input__icon el-icon-search"></i>
</div> </div>
</div> </div>
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
<st-button type="primary" @click="$router.push({ path: '/params/add', query: { level: 2 } })"> <st-button type="primary" @click="$router.push({ path: '/params/add', query: { level: 2 } })">
<i class="iconfont icon-tianjia"></i><span class="text">{{'添加'}}</span></st-button> <i class="iconfont icon-tianjia"></i><span class="text">{{'添加'}}</span></st-button>
<div class="search"> <div class="search">
<input type="text" class="search-input" placeholder="请输入搜索内容" v-model="twoVal"> <input type="text" class="search-input" placeholder="请输入搜索内容" v-model="twoVal" @input="getTwoData">
<i class="el-input__icon el-icon-search"></i> <i class="el-input__icon el-icon-search"></i>
</div> </div>
</div> </div>
...@@ -130,7 +130,7 @@ export default { ...@@ -130,7 +130,7 @@ export default {
methods: { methods: {
async getOneData() { async getOneData() {
this.loadingOne = true this.loadingOne = true
const oneLevel = await getParameter({ base: 1, pages: this.oneCurrentPage - 1, pagesize: 10 }) const oneLevel = await getParameter({ base: 1, pages: this.oneCurrentPage - 1, pagesize: 10, name: this.oneVal })
if (oneLevel && oneLevel.data && oneLevel.data.code === 0) { if (oneLevel && oneLevel.data && oneLevel.data.code === 0) {
this.oneList = oneLevel.data.parameters.datas.map((item, index) => { this.oneList = oneLevel.data.parameters.datas.map((item, index) => {
item.order = index + 1 + (this.oneCurrentPage - 1) * 10 item.order = index + 1 + (this.oneCurrentPage - 1) * 10
...@@ -142,7 +142,7 @@ export default { ...@@ -142,7 +142,7 @@ export default {
}, },
async getTwoData() { async getTwoData() {
this.loadingTwo = true this.loadingTwo = true
const twoLevel = await getParameter({ parent: this.parentLevel === '' ? 0 : this.parentLevel, pages: this.twoCurrentPage - 1, pagesize: 10 }) const twoLevel = await getParameter({ parent: this.parentLevel === '' ? 0 : this.parentLevel, pages: this.twoCurrentPage - 1, pagesize: 10, name: this.twoVal })
if (twoLevel && twoLevel.data && twoLevel.data.code === 0) { if (twoLevel && twoLevel.data && twoLevel.data.code === 0) {
this.twoList = twoLevel.data.parameters.datas.map((item, index) => { this.twoList = twoLevel.data.parameters.datas.map((item, index) => {
item.order = index + 1 + (this.twoCurrentPage - 1) * 10 item.order = index + 1 + (this.twoCurrentPage - 1) * 10
...@@ -194,6 +194,8 @@ export default { ...@@ -194,6 +194,8 @@ export default {
height: calc(100% - 60px) height: calc(100% - 60px)
.list-content .list-content
height: 100% height: 100%
::v-deep .current-row td:last-child
border-right: 4px solid #409EFF
.table-box .table-box
height: 100% height: 100%
::v-deep.el-table ::v-deep.el-table
......
...@@ -11,17 +11,30 @@ ...@@ -11,17 +11,30 @@
<st-form-item <st-form-item
style="margin-bottom:10px" style="margin-bottom:10px"
:label="'头像'+':'"> :label="'头像'+':'">
<el-image style="width: 80px; height: 80px" :src="userData.image" fit="fit"></el-image> <el-upload
ref="mask-images"
accept=".jpg,.jpeg,.png,.bmp"
:class="{disabled: imageList.length >= 1}"
action=""
:limit="1"
:file-list="imageList"
list-type="picture-card"
:on-change="handleChange"
:on-remove="handleRemove"
:auto-upload="false">
<i class="el-icon-plus" ></i>
<!-- <span v-if="!imageList.length" style="position: absolute;top: 30px;left: 46px">上传照片</span> -->
</el-upload>
</st-form-item> </st-form-item>
<st-form-item <st-form-item
style="margin-bottom:10px" style="margin-bottom:10px"
:label="'账户'+':'"> :label="'账户'+':'">
<span>{{userData.role}}</span> <span>{{userData.username}}</span>
</st-form-item> </st-form-item>
<st-form-item <st-form-item
style="margin-bottom:10px" style="margin-bottom:10px"
:label="'姓名'+':'"> :label="'姓名'+':'">
<span>{{userData.creater}}</span><span class="btn-text" @click="showDialog = true;type = 'name'">编辑</span> <span>{{userData.nickname}}</span><span class="btn-text" @click="showDialog = true;type = 'name';form = JSON.parse(JSON.stringify(userData))">编辑</span>
</st-form-item> </st-form-item>
<st-form-item <st-form-item
style="margin-bottom:10px" style="margin-bottom:10px"
...@@ -43,28 +56,25 @@ ...@@ -43,28 +56,25 @@
<div slot="header" class="popup-header">{{'编辑'}}</div> <div slot="header" class="popup-header">{{'编辑'}}</div>
<div slot="body" class="popup-body"> <div slot="body" class="popup-body">
<st-form <st-form
:label-width="type === 'password' ? '90px' : ''" :label-width="type === 'password' ? '100px' : ''"
ref="form"> ref="form"
<st-form-item v-if="type === 'email'" :model="form"
:label="'邮箱:'"> :rules="rules">
<st-input v-model="email"></st-input> <st-form-item v-if="type === 'email'" :label="'邮箱:'" prop="email">
<st-input v-model="form.email"></st-input>
</st-form-item> </st-form-item>
<st-form-item v-if="type === 'name'" <st-form-item v-if="type === 'name'" :label="'姓名:'" prop="nickname">
:label="'姓名:'"> <st-input v-model="form.nickname"></st-input>
<st-input v-model="name"></st-input>
</st-form-item> </st-form-item>
<div v-if="type === 'password'"> <div v-if="type === 'password'">
<st-form-item <st-form-item :label="'当前密码:'" prop="password">
:label="'当前密码:'"> <st-input v-model="form.password" type="password"></st-input>
<st-input v-model="password"></st-input>
</st-form-item> </st-form-item>
<st-form-item <st-form-item :label="'新密码:'" prop="newPwd">
:label="'新密码:'"> <st-input v-model="form.newPwd" type="password"></st-input>
<st-input v-model="newPwd"></st-input>
</st-form-item> </st-form-item>
<st-form-item <st-form-item :label="'确认新密码:'" prop="confirmPwd">
:label="'新密码:'"> <st-input v-model="form.confirmPwd" type="password"></st-input>
<st-input v-model="confirmPwd"></st-input>
</st-form-item> </st-form-item>
</div> </div>
</st-form> </st-form>
...@@ -78,26 +88,139 @@ ...@@ -78,26 +88,139 @@
</template> </template>
<script> <script>
import { editUser } from '@/axios'
import { getUser } from '@/utils/user' import { getUser } from '@/utils/user'
import browserStorage from '@/services/local-storage'
export default { export default {
data() { data() {
const validatePassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入密码'))
} else if (!(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\-_]{8,64}$/.test(value))) {
callback(new Error('密码必须包含大小写字母和数字,大于8位且小于64位'))
} else {
callback()
}
}
const validatePasswordConfirmation = (rule, value, callback) => {
if (value === '') {
callback(new Error('请确认密码'))
} else if (value !== this.confirmPwd) {
callback(new Error('密码与确认密码不一致'))
} else {
callback()
}
}
return { return {
showDialog: false, showDialog: false,
userData: {}, userData: {},
form: {},
imageList: [],
type: '', type: '',
email: '', email: '',
name: '', name: '',
password: '', password: '',
newPwd: '', newPwd: '',
confirmPwd: '' confirmPwd: '',
rules: {
nickname: [
{ required: true, message: '请输入姓名' }
],
email: [
{ required: true, message: '请输入邮箱' },
{ type: 'email', message: '邮箱格式不正确' },
],
password: [
{ required: true, message: '请输入密码' },
{ validator: validatePassword, message: '密码必须包含大小写字母和数字,大于8位且小于64位' },
],
newPwd: [
{ required: true, message: '请输入密码' },
{ validator: validatePassword, message: '密码必须包含大小写字母和数字,大于8位且小于64位' },
],
confirmPwd: [
{ required: true, message: '请确认密码' },
{ validator: validatePasswordConfirmation, trigger: 'blur', message: '密码与确认密码不一致' },
],
}
} }
}, },
mounted() { mounted() {
this.userData = getUser().info this.userData = getUser().info
this.userData.username = browserStorage.getItem('username')
this.userData.nickname = browserStorage.getItem('nickname')
this.imageList = [{ url: browserStorage.getItem('image') }]
this.userData.email = browserStorage.getItem('email')
}, },
methods: { methods: {
submit() { submit() {
this.$refs.form.validate(async valid => {
if (valid) {
let res = {}
switch (this.type) {
case 'name': res = await editUser({ username: browserStorage.getItem('username'), nickname: this.form.nickname })
if (res && res.data && res.data.code === 0) {
browserStorage.setItem('nickname', this.form.nickname)
this.userData.nickname = browserStorage.getItem('nickname')
Toast.success('操作成功')
}
break
case 'email': res = await editUser({ username: browserStorage.getItem('username'), email: this.form.email })
if (res && res.data && res.data.code === 0) {
browserStorage.setItem('email', this.form.email)
this.userData.email = browserStorage.getItem('email')
Toast.success('操作成功')
}
break
case 'password': res = await editUser({ username: browserStorage.getItem('username'), password: this.form.password, new_password: this.form.newPwd })
if (res && res.data && res.data.code === 0) {
Toast.success('操作成功')
}
break
default:
break
}
this.showDialog = false this.showDialog = false
}
})
},
fileToBase64(file) {
return new Promise((resolve, reject) => {
try {
const read = new FileReader()
read.onload = function(e) {
resolve(e.target.result)
}
read.readAsDataURL(file)
} catch (err) {
reject(err)
}
})
},
async handleChange(file, fileList) {
this.imageList = fileList
if (file.size > 64 * 1024) {
Toast.danger('图片大小不能超过64KB')
this.imageList = []
return
}
const base64 = await this.fileToBase64(file.raw)
const res = await editUser({ username: browserStorage.getItem('username'), image: base64 })
if (res && res.data && res.data.code === 0) {
browserStorage.setItem('image', base64)
this.imageList[0].url = base64
} else {
this.imageList = []
}
},
async handleRemove(file, fileList) {
this.imageList = []
const res = await editUser({ username: browserStorage.getItem('username'), image: '' })
if (res && res.data && res.data.code === 0) {
browserStorage.setItem('image', '')
} else {
this.imageList = [{ url: browserStorage.getItem('image') }]
}
}, },
cancelSubmit() { cancelSubmit() {
this.showDialog = false this.showDialog = false
...@@ -107,6 +230,9 @@ export default { ...@@ -107,6 +230,9 @@ export default {
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
.disabled
::v-deep .el-upload--picture-card
display: none
.page-content .page-content
text-align: left text-align: left
.btn-text .btn-text
......
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
<div class="header"> <div class="header">
<span class="title">{{'设置中心'}}</span> <span class="title">{{'设置中心'}}</span>
</div> </div>
<div class="page-content"> <img src="@/assets/unresolved.png" alt="">
</div> <!-- <div class="page-content">
</div> -->
</div> </div>
</template> </template>
......
...@@ -293,7 +293,11 @@ export default { ...@@ -293,7 +293,11 @@ export default {
// TokenId // TokenId
browserStorage.setItem('token', res.data.token) browserStorage.setItem('token', res.data.token)
browserStorage.setItem('user', JSON.stringify(res.data)) browserStorage.setItem('user', JSON.stringify(res.data))
this.$router.push({ path: '/params' }) browserStorage.setItem('image', res.data.image)
browserStorage.setItem('email', res.data.email)
browserStorage.setItem('nickname', res.data.nickname)
browserStorage.setItem('username', this.userName)
this.$router.push({ path: '/overview' })
} else { } else {
Toast.danger(res.data.msg) Toast.danger(res.data.msg)
} }
......
<template>
<div class="data-list-common flex column main-content flex-1">
<div class="page-content">
<div class="apply">
<span style="margin-right: 30px">当前应用:<span v-if="applyInfo">{{applyInfo.appid}}</span></span>
<el-button type="primary" size="small" @click="$router.push({ name: 'apply' })">切换</el-button>
<div style="margin-left: 70px" v-if="applyInfo">{{applyInfo.description}}</div>
</div>
<div id="main"></div>
</div>
</div>
</template>
<script>
import { getApp, getAccount } from '@/axios'
import * as echarts from 'echarts'
export default {
data() {
return {
applyInfo: {},
devicesInfo: {},
myChart: null,
option: {}
}
},
mounted() {
const chartDom = document.getElementById('main')
this.myChart = echarts.init(chartDom)
this.getApply()
this.getAccount()
this.repint()
},
methods: {
async getApply() {
const res = await getApp({ pages: 0, pagesize: 100000000 })
if (res && res.data && res.data.code === 0) {
this.applyInfo = res.data.data.apps.filter(item => item.ismainapp === 1)[0]
}
},
repint() {
window.onresize = () => {
setTimeout(() => {
this.myChart.resize()
}, 10)
}
},
async getAccount() {
const res = await getAccount()
if (res && res.data && res.data.code === 0) {
this.devicesInfo = res.data
this.myChart.setOption({
tooltip: {
trigger: 'item'
},
series: [
{
name: '设备状态',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: true,
labelLine: {
show: true
},
data: [
{ value: res.data.onlines, name: '在线' },
{ value: res.data.offlines, name: '离线' },
{ value: res.data.exceptions, name: '异常' },
]
}
]
})
}
}
}
}
</script>
<style lang="sass" scoped>
.apply
text-align: left
.box
width: 100%
height: 100%
#main
width: 100%
height: 100%
display: flex
justify-content: center
</style>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!