This commit is contained in:
2025-02-06 18:13:42 +08:00
commit f4eb06d284
492 changed files with 40280 additions and 0 deletions

View File

@ -0,0 +1,360 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item label="字典名称" prop="dictType">
<el-select v-model="queryParams.dictType" size="small">
<el-option
v-for="item in typeOptions"
:key="item.dictId"
:label="item.dictName"
:value="item.dictType"
/>
</el-select>
</el-form-item>
<el-form-item label="字典标签" prop="dictLabel">
<el-input
v-model="queryParams.dictLabel"
placeholder="请输入字典标签"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictData:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictData:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictData:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="dataList" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典编码" width="80" align="center" prop="dictCode" />
<el-table-column label="字典标签" align="center" prop="dictLabel" />
<el-table-column label="字典键值" align="center" prop="dictValue" />
<el-table-column label="字典排序" align="center" prop="dictSort" />
<el-table-column label="状态" align="center" prop="status" :formatter="statusFormat" />
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createdAt" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysDictData:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysDictData:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典类型">
<el-input v-model="form.dictType" :disabled="true" />
</el-form-item>
<el-form-item label="数据标签" prop="dictLabel">
<el-input v-model="form.dictLabel" placeholder="请输入数据标签" :disabled="isEdit" />
</el-form-item>
<el-form-item label="数据键值" prop="dictValue">
<el-input v-model="form.dictValue" placeholder="请输入数据键值" :disabled="isEdit" />
</el-form-item>
<el-form-item label="显示排序" prop="dictSort">
<el-input-number v-model="form.dictSort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listData, getData, delData, addData, updateData, exportData } from '@/api/admin/dict/data'
import { listType, getType } from '@/api/admin/dict/type'
export default {
name: 'SysDictDataManage',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 字典表格数据
dataList: [],
// 默认字典类型
defaultDictType: '',
// 弹出层标题
title: '',
isEdit: false,
// 是否显示弹出层
open: false,
// 状态数据字典
statusOptions: [],
// 类型数据字典
typeOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
dictName: undefined,
dictType: undefined,
status: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {
dictLabel: [
{ required: true, message: '数据标签不能为空', trigger: 'blur' }
],
dictValue: [
{ required: true, message: '数据键值不能为空', trigger: 'blur' }
],
dictSort: [
{ required: true, message: '数据顺序不能为空', trigger: 'blur' }
]
}
}
},
created() {
const dictId = this.$route.params && this.$route.params.dictId
this.getType(dictId)
this.getTypeList()
this.getDicts('sys_normal_disable').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询字典类型详细 */
getType(dictId) {
getType(dictId).then(response => {
this.queryParams.dictType = response.data.dictType
this.defaultDictType = response.data.dictType
this.getList()
})
},
/** 查询字典类型列表 */
getTypeList() {
listType({ pageSize: 1000 }).then(response => {
this.typeOptions = response.data.list
})
},
/** 查询字典数据列表 */
getList() {
this.loading = true
listData(this.queryParams).then(response => {
this.dataList = response.data.list
this.total = response.data.count
this.loading = false
})
},
// 数据状态字典翻译
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
dictCode: undefined,
dictLabel: undefined,
dictValue: undefined,
dictSort: 0,
status: '2',
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.queryParams.dictType = this.defaultDictType
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加字典数据'
this.isEdit = false
this.form.dictType = this.queryParams.dictType
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.dictCode)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const dictCode = row.dictCode || this.ids
getData(dictCode).then(response => {
this.form = response.data
this.form.status = String(this.form.status)
this.open = true
this.title = '修改字典数据'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.form.status = parseInt(this.form.status)
if (this.form.dictCode !== undefined) {
updateData(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addData(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const dictCodes = (row.dictCode && [row.dictCode]) || this.ids
this.$confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delData({ 'ids': dictCodes })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams
this.$confirm('是否确认导出所有数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return exportData(queryParams)
}).then(response => {
this.download(response.msg)
}).catch(function() {})
}
}
}
</script>

View File

@ -0,0 +1,360 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="字典名称" prop="dictName">
<el-input
v-model="queryParams.dictName"
placeholder="请输入字典名称"
clearable
size="small"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input
v-model="queryParams.dictType"
placeholder="请输入字典类型"
clearable
size="small"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="字典状态"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictType:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictType:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictType:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysDictType:export']"
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="typeList" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典编号" width="80" align="center" prop="id" />
<el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" />
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
<router-link :to="{name:'SysDictDataManage', params: {dictId:scope.row.id}}" class="link-type">
<span>{{ scope.row.dictType }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" :formatter="statusFormat" />
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createdAt" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysDictType:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysDictType:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典名称" prop="dictName">
<el-input v-model="form.dictName" placeholder="请输入字典名称" :disabled="isEdit" />
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input v-model="form.dictType" placeholder="请输入字典类型" :disabled="isEdit" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listType, getType, delType, addType, updateType } from '@/api/admin/dict/type'
import { formatJson } from '@/utils'
export default {
name: 'SysDictTypeManage',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 字典表格数据
typeList: [],
// 弹出层标题
title: '',
isEdit: false,
// 是否显示弹出层
open: false,
// 状态数据字典
statusOptions: [],
// 日期范围
dateRange: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
dictName: undefined,
dictType: undefined,
status: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {
dictName: [
{ required: true, message: '字典名称不能为空', trigger: 'blur' }
],
dictType: [
{ required: true, message: '字典类型不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getList()
this.getDicts('sys_normal_disable').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询字典类型列表 */
getList() {
this.loading = true
listType(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.typeList = response.data.list
this.total = response.data.count
this.loading = false
})
},
// 字典状态字典翻译
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, parseInt(row.status))
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
dictName: undefined,
dictType: undefined,
status: '2',
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加字典类型'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const dictId = row.id || this.ids
getType(dictId).then(response => {
this.form = response.data
this.form.status = String(this.form.status)
this.open = true
this.title = '修改字典类型'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.form.status = parseInt(this.form.status)
if (this.form.id !== undefined) {
updateType(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addType(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const dictIds = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delType({ 'ids': dictIds })
}).then(() => {
this.getList()
this.msgSuccess('删除成功')
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
// const queryParams = this.queryParams
this.$confirm('是否确认导出所有类型数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['字典编号', '字典名称', '字典类型', '状态', '备注']
const filterVal = ['id', 'dictName', 'dictType', 'status', 'remark']
const list = this.typeList
const data = formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: '字典管理',
autoWidth: true, // Optional
bookType: 'xlsx' // Optional
})
this.downloadLoading = false
})
})
}
}
}
</script>

View File

@ -0,0 +1,287 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineAccountSetting:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineAccountSetting:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineAccountSetting:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineAccountSettingList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/><el-table-column label="用户" align="center" prop="userName"
:show-overflow-tooltip="true"/><el-table-column label="密码" align="center" prop="password"
:show-overflow-tooltip="true"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineAccountSetting:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineAccountSetting:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户" prop="userName">
<el-input v-model="form.userName" placeholder="用户"
/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" placeholder="密码"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineAccountSetting, delLineAccountSetting, getLineAccountSetting, listLineAccountSetting, updateLineAccountSetting} from '@/api/admin/line-account-setting'
export default {
name: 'LineAccountSetting',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineAccountSettingList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineAccountSetting(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineAccountSettingList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
userName: undefined,
password: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加登录账户管理'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineAccountSetting(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改登录账户管理'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineAccountSetting(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineAccountSetting(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineAccountSetting( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,344 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="90px">
<el-form-item label="用户组名称" prop="groupName"><el-input
v-model="queryParams.groupName"
placeholder="请输入用户组名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineApiGroup:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:lineApiGroup:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col> -->
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:lineApiGroup:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col> -->
</el-row>
<el-table v-loading="loading" :data="lineApiGroupList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /><el-table-column
label="ID"
align="center"
prop="id"
:show-overflow-tooltip="true"
/><el-table-column
label="用户组名称"
align="center"
prop="groupName"
:show-overflow-tooltip="true"
/><el-table-column
label="绑定账户"
align="center"
prop="apiUserId"
:show-overflow-tooltip="true"
>
<template #default="{row}">
{{ [row.a_api_name,row.b_api_name].toString() }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<!-- <el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineApiGroup:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm> -->
<el-popconfirm
class="delete-popconfirm"
title="确认要解绑吗?"
confirm-button-text="解绑"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineApiGroup:remove']"
size="mini"
type="text"
>解绑
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="110px">
<el-form-item label="用户组名称" prop="groupName">
<el-input
v-model="form.groupName"
placeholder="用户组名称"
/>
</el-form-item>
<el-form-item label="主账号" prop="pid">
<el-select v-model="form.pid" placeholder="请选择主账号" style="width: 100%;">
<el-option v-for="(a,i) in accounts" :key="i" :value="a.id" :label="a.apiName" />
</el-select>
</el-form-item>
<el-form-item label="副账号" prop="sid">
<el-select v-model="form.sid" placeholder="请选择副账号" style="width: 100%;">
<el-option v-for="(a,i) in comAccounts" :key="i" :value="a.id" :label="a.apiName" />
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { delLineApiGroup, getLineApiGroup, listLineApiGroup, updateLineApiGroup, getUser, userbind } from '@/api/admin/line-api-group'
export default {
name: 'LineApiGroup',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineApiGroupList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
groupName: undefined,
},
accounts: [],
// 表单参数
form: {
},
pid: undefined,
sid: undefined,
// 表单校验
rules: {
groupName: [{ required: true, message: '用户组名称不能为空', trigger: 'blur' }],
pid: [{ required: true, message: '主账号不能为空', trigger: 'blur' }],
sid: [{ required: true, message: '副账号不能为空', trigger: 'blur' }]
}
}
},
computed: {
comAccounts() {
return this.accounts.filter(a => a.id !== this.form.pid)
}
},
created() {
this.getList()
getUser().then(response => {
this.accounts = response.data
})
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineApiGroup(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineApiGroupList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
groupName: undefined,
apiUserId: undefined,
pid: undefined,
sid: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加用户绑定从属关系表'
this.isEdit = false
getUser().then(response => {
this.accounts = response.data
})
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineApiGroup(id).then(response => {
const { data } = response || {}
this.form = data
this.open = true
this.title = '修改用户绑定从属关系表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineApiGroup(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
const { groupName, pid, sid } = this.form
userbind({ group_name: groupName, user_id_str: `${pid},${sid}` }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认解绑编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineApiGroup({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
getUser().then(response => {
this.accounts = response.data
})
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,472 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineApiUser:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineApiUser:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineApiUser:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineApiUserList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /><el-table-column label="用户名" align="center" prop="userId" :formatter="userIdFormat" width="100">
<template slot-scope="scope">
{{ userIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column
label="api用户名"
align="center"
prop="apiName"
:show-overflow-tooltip="true"
/><el-table-column
label="apiKey"
align="center"
prop="apiKey"
:show-overflow-tooltip="true"
/><el-table-column
label="apiSecret"
align="center"
prop="apiSecret"
:show-overflow-tooltip="true"
/><el-table-column
label="代理地址"
align="center"
prop="ipAddress"
:show-overflow-tooltip="true"
/>
<!-- <el-table-column
label="代码账号密码"
align="center"
prop="userPass"
:show-overflow-tooltip="true"
/> -->
<!-- <el-table-column
label="归属"
align="center"
prop="affiliation"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['现货','合约','现货合约'][row.affiliation-1] }}</template>
</el-table-column> -->
<el-table-column
label="是否超管可见"
align="center"
prop="adminShow"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['否','是'][row.adminShow] }}</template>
</el-table-column>
<!-- <el-table-column
label="允许下单的方向"
align="center"
prop="site"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['多','空','多空'][row.site-1] }}</template>
</el-table-column> -->
<el-table-column
label="从属关系"
align="center"
prop="subordinate"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['','主账号','副帐号'][row.subordinate] }}</template>
</el-table-column><el-table-column label="所属组id" align="center" prop="groupId" :formatter="groupIdFormat" width="100">
<template slot-scope="scope">
{{ groupIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column
label="开启状态"
align="center"
prop="openStatus"
:show-overflow-tooltip="true"
>
<template #default="{row}"><el-tag size="mini" :type="['danger','success'][row.openStatus]">{{ ['已关闭','已开启'][row.openStatus] }}</el-tag></template>
</el-table-column>
<el-table-column
label="合约最后通信时间"
align="center"
width="180"
prop="futuresLastTime"
:show-overflow-tooltip="true"
/>
<el-table-column
label="现货最后通信时间"
align="center"
prop="spotLastTime"
width="180"
:show-overflow-tooltip="true"
/>
<el-table-column label="操作" fixed="right" width="150" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineApiUser:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineApiUser:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<!-- <el-form-item label="用户id" prop="userId">
<el-input v-model="form.userId" placeholder="用户id"
/>
</el-form-item> -->
<!-- <el-form-item label="关联交易所账号id" prop="jysId">
<el-input v-model="form.jysId" placeholder="关联交易所账号id"
/>
</el-form-item> -->
<el-form-item label="api用户名" prop="apiName">
<el-input
v-model="form.apiName"
placeholder="api用户名"
/>
</el-form-item>
<el-form-item label="apiKey" prop="apiKey">
<el-input
v-model="form.apiKey"
placeholder="apiKey"
/>
</el-form-item>
<el-form-item label="apiSecret" prop="apiSecret">
<el-input
v-model="form.apiSecret"
placeholder="apiSecret"
/>
</el-form-item>
<el-form-item label="代理地址" prop="ipAddress">
<el-input
v-model="form.ipAddress"
placeholder="代理地址"
/>
</el-form-item>
<el-form-item label="代码账号密码" prop="userPass">
<el-input
v-model="form.userPass"
placeholder="代码账号密码"
/>
</el-form-item>
<!-- <el-form-item label="管理员id" prop="adminId">
<el-input v-model="form.adminId" placeholder="管理员id"
/>
</el-form-item> -->
<!-- <el-form-item label="归属" prop="affiliation">
<el-radio-group v-model="form.affiliation">
<el-radio :label="3">现货合约</el-radio>
<el-radio :label="1">现货</el-radio>
<el-radio :label="2">合约</el-radio>
</el-radio-group>
</el-form-item> -->
<!-- <el-form-item label="是否超管可见" prop="adminShow">
<el-input v-model="form.adminShow" placeholder="是否超管可见"
/>
</el-form-item> -->
<!-- <el-form-item label="允许下单的方向" prop="site">
<el-radio-group v-model="form.site">
<el-radio label="3">多空</el-radio>
<el-radio label="1"></el-radio>
<el-radio label="2"></el-radio>
</el-radio-group>
</el-form-item> -->
<!-- <el-form-item label="从属关系" prop="subordinate">
<el-input v-model="form.subordinate" placeholder="从属关系"
/>
</el-form-item> -->
<!-- <el-form-item label="所属组id" prop="groupId">
<el-input v-model="form.groupId" placeholder="所属组id"
/>
</el-form-item> -->
<el-form-item label="开启状态" prop="openStatus">
<el-radio-group v-model="form.openStatus">
<el-radio :label="1">开启</el-radio>
<el-radio :label="0">关闭</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLineApiUser, delLineApiUser, getLineApiUser, listLineApiUser, updateLineApiUser } from '@/api/admin/line-api-user'
import { listLineUser } from '@/api/admin/line-user'
import { listLineApiGroup } from '@/api/admin/line-api-group'
export default {
name: 'LineApiUser',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineApiUserList: [],
// 关系表类型
userIdOptions: [],
groupIdOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
this.getLineUserItems()
this.getLineApiGroupItems()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineApiUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineApiUserList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
userId: undefined,
jysId: undefined,
apiName: undefined,
apiKey: undefined,
apiSecret: undefined,
ipAddress: undefined,
userPass: undefined,
adminId: undefined,
affiliation: 3,
adminShow: undefined,
site: '3',
subordinate: '0',
groupId: undefined,
openStatus: 1
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
userIdFormat(row) {
return this.selectItemsLabel(this.userIdOptions, row.userId)
},
groupIdFormat(row) {
return this.selectItemsLabel(this.groupIdOptions, row.groupId)
},
// 关系
getLineUserItems() {
this.getItems(listLineUser, undefined).then(res => {
this.userIdOptions = this.setItems(res, 'id', 'username')
})
},
getLineApiGroupItems() {
this.getItems(listLineApiGroup, undefined).then(res => {
this.groupIdOptions = this.setItems(res, 'id', 'groupName')
})
},
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加api用户管理'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineApiUser(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改api用户管理'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineApiUser(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineApiUser(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineApiUser({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,305 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineCoinnetwork:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineCoinnetwork:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineCoinnetwork:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineCoinnetworkList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineCoinnetwork:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineCoinnetwork:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="网络名称" prop="networkName">
<el-input v-model="form.networkName" placeholder="网络名称"
/>
</el-form-item>
<el-form-item label="网络token名称" prop="tokenName">
<el-input v-model="form.tokenName" placeholder="网络token名称"
/>
</el-form-item>
<el-form-item label="充值区块确认数" prop="arrivalNum">
<el-input v-model="form.arrivalNum" placeholder="充值区块确认数"
/>
</el-form-item>
<el-form-item label="提现解锁确认数" prop="unlockNum">
<el-input v-model="form.unlockNum" placeholder="提现解锁确认数"
/>
</el-form-item>
<el-form-item label="提现确认平均时间,单位分钟" prop="unlockTime">
<el-input v-model="form.unlockTime" placeholder="提现确认平均时间,单位分钟"
/>
</el-form-item>
<el-form-item label="网络手续费,该字段是动态的,后面会有服务定时更新该字段" prop="fee">
<el-input v-model="form.fee" placeholder="网络手续费,该字段是动态的,后面会有服务定时更新该字段"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineCoinnetwork, delLineCoinnetwork, getLineCoinnetwork, listLineCoinnetwork, updateLineCoinnetwork} from '@/api/admin/line-coinnetwork'
export default {
name: 'LineCoinnetwork',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineCoinnetworkList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineCoinnetwork(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineCoinnetworkList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
networkName: undefined,
tokenName: undefined,
arrivalNum: undefined,
unlockNum: undefined,
unlockTime: undefined,
fee: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加【币种网络】'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineCoinnetwork(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改【币种网络】'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineCoinnetwork(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineCoinnetwork(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineCoinnetwork( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,401 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineCointonetwork:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineCointonetwork:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineCointonetwork:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineCointonetworkList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineCointonetwork:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineCointonetwork:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="币种id" prop="coinId">
<el-input v-model="form.coinId" placeholder="币种id"
/>
</el-form-item>
<el-form-item label="公链网络id" prop="networkId">
<el-input v-model="form.networkId" placeholder="公链网络id"
/>
</el-form-item>
<el-form-item label="是否主网--1否,3是.比如BTC在BTC网络中就属于主网" prop="isMain">
<el-input v-model="form.isMain" placeholder="是否主网--1否,3是.比如BTC在BTC网络中就属于主网"
/>
</el-form-item>
<el-form-item label="是否开启充值:1==否,3==是" prop="isDeposit">
<el-input v-model="form.isDeposit" placeholder="是否开启充值:1==否,3==是"
/>
</el-form-item>
<el-form-item label="是否开启提现:1==否,3==是" prop="isWithdraw">
<el-input v-model="form.isWithdraw" placeholder="是否开启提现:1==否,3==是"
/>
</el-form-item>
<el-form-item label="币种代号" prop="coinCode">
<el-input v-model="form.coinCode" placeholder="币种代号"
/>
</el-form-item>
<el-form-item label="代币token" prop="token">
<el-input v-model="form.token" placeholder="代币token"
/>
</el-form-item>
<el-form-item label="最小充值数量" prop="minChargeNum">
<el-input v-model="form.minChargeNum" placeholder="最小充值数量"
/>
</el-form-item>
<el-form-item label="单笔最小提币数量" prop="minOutNum">
<el-input v-model="form.minOutNum" placeholder="单笔最小提币数量"
/>
</el-form-item>
<el-form-item label="单笔最大提币数量" prop="maxOutNum">
<el-input v-model="form.maxOutNum" placeholder="单笔最大提币数量"
/>
</el-form-item>
<el-form-item label="提币手续费" prop="transferFee">
<el-input v-model="form.transferFee" placeholder="提币手续费"
/>
</el-form-item>
<el-form-item label="币种全称" prop="detailCode">
<el-input v-model="form.detailCode" placeholder="币种全称"
/>
</el-form-item>
<el-form-item label="公链网络简称" prop="networkName">
<el-input v-model="form.networkName" placeholder="公链网络简称"
/>
</el-form-item>
<el-form-item label="公链网络全称" prop="tokenName">
<el-input v-model="form.tokenName" placeholder="公链网络全称"
/>
</el-form-item>
<el-form-item label="手续费类型 1==固定 3==百分比" prop="chargeType">
<el-input v-model="form.chargeType" placeholder="手续费类型 1==固定 3==百分比"
/>
</el-form-item>
<el-form-item label="充值开关时间" prop="rechargeSwitchTime">
<el-date-picker
v-model="form.rechargeSwitchTime"
type="datetime"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
<el-form-item label="提币开关时间" prop="withdrawSwitchTime">
<el-date-picker
v-model="form.withdrawSwitchTime"
type="datetime"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
<el-form-item label="是否开启外部提币免审1==否3==是" prop="isoutsideWithdrawVerify">
<el-input v-model="form.isoutsideWithdrawVerify" placeholder="是否开启外部提币免审1==否3==是"
/>
</el-form-item>
<el-form-item label="外部提币免审阈值" prop="outsideWithdrawVerifyNum">
<el-input v-model="form.outsideWithdrawVerifyNum" placeholder="外部提币免审阈值"
/>
</el-form-item>
<el-form-item label="是否开启内部转账免审1==否3==是" prop="isinsideTransferVerify">
<el-input v-model="form.isinsideTransferVerify" placeholder="是否开启内部转账免审1==否3==是"
/>
</el-form-item>
<el-form-item label="内部转账免审阈值" prop="insidetransferVerifyNum">
<el-input v-model="form.insidetransferVerifyNum" placeholder="内部转账免审阈值"
/>
</el-form-item>
<el-form-item label="每日最大累计提币数量" prop="everydaymaxWithdrawNum">
<el-input v-model="form.everydaymaxWithdrawNum" placeholder="每日最大累计提币数量"
/>
</el-form-item>
<el-form-item label="每日最大免审累计数量" prop="everydaymaxVerifyNum">
<el-input v-model="form.everydaymaxVerifyNum" placeholder="每日最大免审累计数量"
/>
</el-form-item>
<el-form-item label="是否开启内部转账免手续费1==否3==是" prop="isinsidetransferfee">
<el-input v-model="form.isinsidetransferfee" placeholder="是否开启内部转账免手续费1==否3==是"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineCointonetwork, delLineCointonetwork, getLineCointonetwork, listLineCointonetwork, updateLineCointonetwork} from '@/api/admin/line-cointonetwork'
export default {
name: 'LineCointonetwork',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineCointonetworkList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineCointonetwork(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineCointonetworkList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
coinId: undefined,
networkId: undefined,
isMain: undefined,
isDeposit: undefined,
isWithdraw: undefined,
coinCode: undefined,
token: undefined,
minChargeNum: undefined,
minOutNum: undefined,
maxOutNum: undefined,
transferFee: undefined,
detailCode: undefined,
networkName: undefined,
tokenName: undefined,
chargeType: undefined,
rechargeSwitchTime: undefined,
withdrawSwitchTime: undefined,
isoutsideWithdrawVerify: undefined,
outsideWithdrawVerifyNum: undefined,
isinsideTransferVerify: undefined,
insidetransferVerifyNum: undefined,
everydaymaxWithdrawNum: undefined,
everydaymaxVerifyNum: undefined,
isinsidetransferfee: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加币种与网络关系'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineCointonetwork(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改币种与网络关系'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineCointonetwork(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineCointonetwork(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineCointonetwork( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,471 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="90px">
<el-form-item label="交易对" prop="symbol"><el-input
v-model="queryParams.symbol"
placeholder="请输入交易对"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="交易对类型" prop="type">
<el-select
v-model="queryParams.type"
placeholder="请选择类型"
clearable
size="small"
>
<el-option
v-for="dict in [{l:'现货',v:'1'},{l:'合约',v:'2'}]"
:key="dict.k"
:label="dict.l"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item label="预估方向" prop="direction"><el-input
v-model="queryParams.direction"
placeholder="请输入预估方向"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:lineDirection:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineDirection:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button type="primary" icon="el-icon-refresh" size="mini" :loading="loading" @click="reloadGroup">重置分组</el-button>
<el-button
v-permisaction="['admin:lineDirection:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineDirectionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /><el-table-column
label="交易对"
align="center"
prop="symbol"
:show-overflow-tooltip="true"
/><el-table-column
label="交易对类型"
align="center"
prop="type"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
{{ scope.row.type==1?"现货":"合约" }}
</template>
</el-table-column>
<el-table-column
label="买入点一"
align="center"
prop="buyPoint1"
:show-overflow-tooltip="true"
/><el-table-column
label="买入点二"
align="center"
prop="buyPoint2"
:show-overflow-tooltip="true"
/><el-table-column
label="买入点三"
align="center"
prop="buyPoint3"
:show-overflow-tooltip="true"
/><el-table-column
label="卖出点一"
align="center"
prop="sellPoint1"
:show-overflow-tooltip="true"
/><el-table-column
label="卖出点二"
align="center"
prop="sellPoint2"
:show-overflow-tooltip="true"
/><el-table-column
label="卖出点三"
align="center"
prop="sellPoint3"
:show-overflow-tooltip="true"
/><el-table-column
label="预估方向"
align="center"
prop="direction"
:show-overflow-tooltip="true"
/><el-table-column
label="AI智能分析"
align="center"
prop="aiAnswer"
:show-overflow-tooltip="true"
/>
<el-table-column
label="创建时间"
align="center"
prop="createdAt"
width="150"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ parseTime(row.createdAt) }}</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<!-- <el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineDirection:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm> -->
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineDirection:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="交易对" prop="symbol">
<el-input
v-model="form.symbol"
placeholder="交易对"
/>
</el-form-item>
<el-form-item label="交易对类型:1=现货,2=合约" prop="type">
<el-radio-group v-model="form.type">
<el-radio
v-for="dict in typeOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="买入点一" prop="buyPoint1">
<el-input
v-model="form.buyPoint1"
placeholder="买入点一"
/>
</el-form-item>
<el-form-item label="买入点二" prop="buyPoint2">
<el-input
v-model="form.buyPoint2"
placeholder="买入点二"
/>
</el-form-item>
<el-form-item label="买入点三" prop="buyPoint3">
<el-input
v-model="form.buyPoint3"
placeholder="买入点三"
/>
</el-form-item>
<el-form-item label="卖出点一" prop="sellPoint1">
<el-input
v-model="form.sellPoint1"
placeholder="卖出点一"
/>
</el-form-item>
<el-form-item label="卖出点二" prop="sellPoint2">
<el-input
v-model="form.sellPoint2"
placeholder="卖出点二"
/>
</el-form-item>
<el-form-item label="卖出点三" prop="sellPoint3">
<el-input
v-model="form.sellPoint3"
placeholder="卖出点三"
/>
</el-form-item>
<el-form-item label="预估方向" prop="direction">
<el-input
v-model="form.direction"
placeholder="预估方向"
/>
</el-form-item>
<el-form-item label="AI智能分析" prop="aiAnswer">
<el-input
v-model="form.aiAnswer"
placeholder="AI智能分析"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLineDirection, delLineDirection, getLineDirection, listLineDirection, updateLineDirection,reloadDirectionGroup } from '@/api/admin/line-direction'
export default {
name: 'LineDirection',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineDirectionList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
symbol: undefined,
type: undefined,
direction: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: { symbol: [{ required: true, message: '交易对不能为空', trigger: 'blur' }],
type: [{ required: true, message: '交易对类型:1=现货,2=合约不能为空', trigger: 'blur' }],
direction: [{ required: true, message: '预估方向不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineDirection(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineDirectionList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
symbol: undefined,
type: undefined,
buyPoint1: undefined,
buyPoint2: undefined,
buyPoint3: undefined,
sellPoint1: undefined,
sellPoint2: undefined,
sellPoint3: undefined,
direction: undefined,
aiAnswer: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加预估方向管理'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineDirection(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改预估方向管理'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineDirection(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineDirection(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineDirection({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
},
/* 重置分组 */
reloadGroup(){
this.loading=true
reloadDirectionGroup()
.then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
} else {
this.msgError(response.msg)
}
this.loading=false
})
},
/** 导出按钮操作 */
handleExport() {
const query = this.queryParams
this.$confirm('是否确认导出所有线路方向数据项?', '警告', {
})
}
}
}
</script>

View File

@ -0,0 +1,789 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="模板名称" prop="name"><el-input
v-model="queryParams.name"
placeholder="请输入模板名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="用户" prop="userId"><el-select
v-model="queryParams.userId"
placeholder="请选择"
clearable
size="small"
>
<el-option
v-for="dict in userIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-form-item> -->
<el-form-item label="模板类型" prop="type">
<el-select
v-model="queryParams.type"
placeholder="请选择模板类型"
clearable
size="small"
>
<el-option
v-for="dict in types"
:key="dict.v"
:label="dict.l"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:lineOrderTemplateLogs:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineOrderTemplateLogs:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineOrderTemplateLogs:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
:disabled="multiple"
@click="handleOrders"
>一键下单
</el-button>
</el-col>
</el-row>
<el-table ref="table" v-loading="loading" :data="lineOrderTemplateLogsList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="id"
align="center"
prop="id"
:show-overflow-tooltip="true"
/>
<el-table-column
label="模板名称"
align="center"
prop="name"
:show-overflow-tooltip="true"
/>
<!-- <el-table-column label="用户id" align="center" prop="userId" :formatter="userIdFormat" width="100">
<template slot-scope="scope">
{{ userIdFormat(scope.row) }}
</template>
</el-table-column> -->
<el-table-column
label="模板类型"
align="center"
prop="type"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['单独添加','批量添加'][row.type-1] }}</template>
</el-table-column><el-table-column
label="开关"
align="center"
prop="switch"
:show-overflow-tooltip="true"
>
<template #default="{row}">
<div @click="onSwitch(row)">
<el-switch
:value="row.switch"
active-value="1"
inactive-value="0"
active-color="#13ce66"
inactive-color="#ff4949"
/>
</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineOrderTemplateLogs:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineOrderTemplateLogs:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="700px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="模板名称" prop="name">
<el-input
v-model="form.name"
placeholder="模板名称"
/>
</el-form-item>
<el-form ref="inForm" :model="inForm" :rules="inRules" label-width="120px" style="height: 500px;overflow: hidden auto;">
<el-form-item label="订单类型" prop="order_type">
<el-radio-group v-model="inForm.order_type" @input="onRadioInput">
<el-radio label="1">现货</el-radio>
<el-radio label="2">合约</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="对冲类型" prop="cover_type">
<el-radio-group v-model="inForm.cover_type">
<el-radio :label="1" :disabled="inForm.order_type==2">现货对合约</el-radio>
<el-radio :label="2" :disabled="inForm.order_type==1">合约对合约</el-radio>
<el-radio :label="3" :disabled="inForm.order_type==1">合约对现货</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="api用户" prop="api_id">
<el-row>
<el-col :span="21">
<el-select
v-model="inForm.api_id"
multiple
style="width: 100%;"
placeholder="请选择api用户"
clearable
filterable
size="small"
>
<el-option
v-for="dict in userIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-col>
<el-col :span="3">
<el-button size="mini" type="primary" style="margin-left: 10px;" @click="onSelectAll">全选</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item v-if="form.type===2" label="交易对组" prop="symbol_group_id">
<el-select
v-if="form.type===2"
v-model="inForm.symbol_group_id"
style="width: 100%;"
placeholder="请选择交易对组"
clearable
filterable
size="small"
>
<el-option
v-for="dict in comSymbols"
:key="dict.id"
:label="dict.groupName"
:value="dict.id"
/>
</el-select>
</el-form-item>
<el-form-item v-else label="交易对" prop="symbol">
<el-select
v-model="inForm.symbol"
style="width: 100%;"
placeholder="请选择交易对"
clearable
filterable
remote
:remote-method="getSymbol"
:loading="searchLoding"
size="small"
>
<el-option
v-for="dict in comSymbols"
:key="dict.id || dict.symbol"
:label="dict.symbol"
:value="dict.symbol"
/>
<div class="page">
<pagination
v-show="symbol.total>0"
:background="false"
:total="symbol.total"
layout="prev, pager, next"
:page.sync="symbol.pageIndex"
:limit.sync="symbol.pageSize"
@pagination="getSymbol"
/>
</div>
</el-select>
</el-form-item>
<el-form-item label="购买方向" prop="site">
<el-radio-group v-model="inForm.site">
<el-radio label="BUY"></el-radio>
<el-radio label="SELL" :disabled="inForm.order_type==1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="购买金额U" prop="buy_price">
<el-input
v-model="inForm.buy_price"
placeholder="购买金额U"
/>
</el-form-item>
<el-form-item label="价格模式" prop="price_pattern">
<el-radio-group v-model="inForm.price_pattern">
<el-radio label="percentage">百分比</el-radio>
<el-radio label="mixture" :disabled="form.type===2">主单实价委托百分比</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="inForm.price_pattern === 'percentage'" label="下单百分比" prop="price">
<el-input
v-model="inForm.price"
placeholder="下单百分比"
/>
</el-form-item>
<el-row v-else type="flex">
<el-col :span="12">
<el-form-item label="下单价(实际价格)" prop="price">
<el-input
v-model="inForm.price"
placeholder="下单价(实际价格)"
/>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="计算百分比">
<el-inputNumber v-model="percenter" controls-position="right" :min="0" style="width: 100px;" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-button type="primary" style="margin-left: 50px;" @click="onCalc">计算</el-button>
</el-col>
</el-row>
<el-form-item label="止盈百分比" prop="profit">
<el-input
v-model="inForm.profit"
placeholder="止盈百分比"
/>
</el-form-item>
<el-form-item label="亏损百分比" prop="stop_price">
<el-input
v-model="inForm.stop_price"
placeholder="亏损百分比"
/>
</el-form-item>
<el-form-item label="对冲百分比" prop="cover_rate">
<el-input
v-model="inForm.cover_rate"
placeholder="对冲百分比"
/>
</el-form-item>
<el-form-item label="加仓后盈利比例" prop="profit_rate">
<el-input
v-model="inForm.profit_rate"
placeholder="加仓后盈利比例"
/>
</el-form-item>
<el-form-item label="对冲平仓最大次数" prop="hedge_close_count">
<el-input
v-model.number="inForm.hedge_close_count"
type="number"
placeholder="对冲平仓最大次数"
/>
</el-form-item>
<el-form-item label="随机累加百分比" prop="hedge_trigger_percent">
<el-row :gutter="20">
<el-col :span="11"><el-input v-model.number="inForm.hedge_trigger_percent" type="number" placeholder="最小值"><template #append>最小值</template></el-input></el-col>
<el-col :span="11"><el-input v-model.number="inForm.hedge_trigger_percent_max" type="number" placeholder="最大值"><template #append>最大值</template></el-input></el-col>
</el-row>
</el-form-item>
<el-form-item label="主单类型" prop="main_order_type">
<el-radio-group v-model="inForm.main_order_type">
<el-radio label="LIMIT">限价</el-radio>
<el-radio label="MARKET">市价</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="对冲单下单类型" prop="hedge_order_type">
<el-radio-group v-model="inForm.hedge_order_type">
<el-radio label="LIMIT">限价</el-radio>
<el-radio label="MARKET">市价</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="加仓主单类型" prop="add_position_main_type">
<el-radio-group v-model="inForm.add_position_main_type">
<el-radio label="LIMIT">限价</el-radio>
<el-radio label="MARKET">市价</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="加仓对冲单类型" prop="add_position_hedge_type">
<el-radio-group v-model="inForm.add_position_hedge_type">
<el-radio label="LIMIT">限价</el-radio>
<el-radio label="MARKET">市价</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="对标价类型" prop="price_type">
<el-radio-group v-model="inForm.price_type">
<el-radio label="new">最新价</el-radio>
<el-radio label="mixture">标记价</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="订单过期时间" prop="profit_rate">
<el-input
v-model.number="inForm.expire_hour"
class="hour"
type="number"
placeholder="订单过期时间"
>
<template slot="append">小时</template>
</el-input>
</el-form-item>
<el-form-item v-if="form.type===2" label="批量下单次数" prop="order_num">
<el-input
v-model.number="inForm.order_num"
min="1"
type="number"
placeholder="批量下单次数"
/>
</el-form-item>
<el-form-item v-if="form.type===2" label="执行类型" prop="script">
<el-radio-group v-model="inForm.script">
<el-radio label="1"><span>脚本执行</span></el-radio>
<el-radio label="0">直接执行</el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="是否保存模板" prop="save_template">
<el-radio-group v-model="inForm.save_template">
<el-radio label="0"></el-radio>
<el-radio label="1">保存并下单</el-radio>
<el-radio label="2">仅保存模板</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="模板名称" prop="template_name">
<el-input
v-model="inForm.template_name"
placeholder="模板名称"
/>
</el-form-item> -->
</el-form>
<el-form-item label="开关" prop="switch">
<el-radio-group v-model="form.switch">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listLineSymbol, getSameSymbol } from '@/api/admin/line-symbol'
import { addLineOrderTemplateLogs, delLineOrderTemplateLogs, getLineOrderTemplateLogs, listLineOrderTemplateLogs, updateLineOrderTemplateLogs } from '@/api/admin/line-order-template-logs'
import { listLineSymbolGroup } from '@/api/admin/line-symbol-group'
import { getMainUser } from '@/api/admin/line-api-user'
import { quickAddPreOrder } from '@/api/admin/line-pre-order'
export default {
name: 'LineOrderTemplateLogs',
components: {
},
data() {
return {
types: [
{ v: 1, l: '单独添加' },
{ v: 2, l: '批量添加' }
],
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineOrderTemplateLogsList: [],
// 关系表类型
userIdOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
name: undefined,
userId: undefined,
type: undefined,
idOrder: 'desc'
},
// 表单参数
form: {
},
// 表单校验
rules: { name: [{ required: true, message: '模板名称不能为空', trigger: 'blur' }],
userId: [{ required: true, message: '用户id不能为空', trigger: 'blur' }],
type: [{ required: true, message: '模板类型:1=单独添加;2=批量添加不能为空', trigger: 'blur' }]
},
symbol: {
symbolList: [],
total: 0,
pageIndex: 1,
pageSize: 6
},
percenter: undefined,
symbolGroups: [],
inRules: {
api_id: [{ required: true, message: 'api用户不能为空', trigger: 'blur' }],
symbol: [{ required: true, message: '交易对不能为空', trigger: 'blur' }],
symbol_group_id: [{ required: true, message: '交易对组不能为空', trigger: 'blur' }],
quote_symbol: [{ required: true, message: '计较货币不能为空', trigger: 'blur' }],
order_sn: [{ required: true, message: '订单号不能为空', trigger: 'blur' }]
},
inForm: {},
searchLoding: false
}
},
computed: {
comSymbols() {
return this.form.type === 2 ? this.symbolGroups : this.symbol.symbolList
}
},
watch: {
'inForm.cover_type'(newValue) {
if (newValue === 3) {
this.inForm.symbol = undefined
this.getSymbol({})
}
}
},
created() {
this.getList()
this.getLineApiUserItems()
this.getSymbolGroup()
},
methods: {
onSelectAll() {
if (this.inForm.api_id && this.inForm.api_id.length > 0) {
this.inForm.api_id = []
return false
}
this.inForm.api_id = this.userIdOptions.map(item => item.key)
},
onRadioInput() {
if (this.inForm.order_type === '1') {
this.inForm.cover_type = 1
} else {
this.inForm.cover_type = 2
}
this.inForm.symbol_group_id = undefined
this.inForm.symbol = undefined
this.getSymbol({})
},
// 交易对列表
getSymbol(e, type) {
this.searchLoding = true
const { pageIndex } = this.symbol
const symbol = typeof e === 'object' ? '' : e
const apiCall = this.form.type === 1 && ([1, 3].includes(this.inForm.cover_type)) ? getSameSymbol : listLineSymbol
apiCall({ pageIndex, pageSize: 6, type: type || this.inForm.order_type, symbol }).then(res => {
this.symbol.total = res.data.count
this.symbol.symbolList = res.data.list
}).finally(() => {
this.searchLoding = false
})
},
// 获取交易对组
getSymbolGroup() {
listLineSymbolGroup({ pageIndex: 1, pageSize: 999, beginTime: undefined, endTime: undefined }).then(res => {
this.symbolGroups = res.data.list
})
},
onCalc() {
if (!this.inForm.price || !this.percenter) {
return 0
}
let res
if (this.inForm.site === 'BUY') {
res = (1 - (this.percenter / 100)) * Number(this.inForm.price)
} else {
res = (1 + (this.percenter / 100)) * Number(this.inForm.price)
}
const [num, decimal] = String(res).split('.')
console.log(num, decimal, '?')
if (decimal) {
this.inForm.price = decimal.length > 4 ? `${num}.${decimal.substring(0, 4)}` : res
} else {
this.inForm.price = res
}
},
/** 查询参数列表 */
getList() {
this.loading = true
listLineOrderTemplateLogs(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineOrderTemplateLogsList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
onSwitch(row) {
const s = row.switch === '1' ? '0' : '1'
updateLineOrderTemplateLogs({ ...row, switch: s }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.getList()
} else {
this.msgError(response.msg)
}
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
name: undefined,
userId: undefined,
params: undefined,
type: 1,
switch: '0'
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
userIdFormat(row) {
return this.selectItemsLabel(this.userIdOptions, row.userId)
},
// 关系
getLineApiUserItems() {
this.getItems(getMainUser, undefined).then(res => {
this.userIdOptions = this.setItems(res, 'id', 'apiName')
})
},
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加委托下单模板'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineOrderTemplateLogs(id).then(response => {
this.form = response.data
const x = JSON.parse(response.data.params)
this.inForm = { ...x, api_id: x.api_id.split(','), symbol_group_id: x.symbol_group_id ? Number(x.symbol_group_id) : undefined }
this.getSymbol(undefined, x.order_type)
this.open = true
this.title = '修改委托下单模板'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.inForm.price = this.inForm.price ? String(this.inForm.price) : ''
if (this.form.id !== undefined) {
this.$refs['inForm'].validate(valided => {
if (!valided) return false
const params = JSON.stringify({
...this.inForm,
symbol_group_id: String(this.inForm.symbol_group_id),
api_id: this.inForm.api_id.toString(),
hedge_trigger_percent: Number(this.inForm.hedge_trigger_percent),
hedge_trigger_percent_max: Number(this.inForm.hedge_trigger_percent_max)
})
updateLineOrderTemplateLogs({ ...this.form, params }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
})
} else {
addLineOrderTemplateLogs({ ...this.inForm, symbol_group_id: String(this.inForm.symbol_group_id), api_id: this.inForm.api_id.toString() }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除id为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineOrderTemplateLogs({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
},
handleOrders() {
const Ids = this.ids
this.$confirm('是否确认一键下单id为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return quickAddPreOrder({ ids: Ids.toString() })
}).then((response) => {
if (response.code === 200) {
this.ids = []
this.$refs.table?.clearSelection()
this.msgSuccess(response.msg)
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>
<style lang="scss" scoped>
.hour{
::v-deep.el-input__inner{
line-height: 1;
}
}
.page{
.pagination-container{
padding: 0 !important;
margin-top: 0;
margin-bottom: 0;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
::v-deep.el-pagination{
width: 100%;
}
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,408 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="api用户" prop="apiId"><el-select
v-model="queryParams.apiId"
placeholder="请选择"
clearable
size="small"
>
<el-option
v-for="dict in apiIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-form-item>
<el-form-item label="执行状态" prop="status"><el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
size="small"
>
<el-option
v-for="dict in status"
:key="dict.k"
:label="dict.k"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:linePreScript:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
v-permisaction="['admin:linePreScript:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:linePreScript:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="linePreScriptList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="id" prop="id" width="55" align="center" />
<el-table-column label="api用户" align="center" prop="apiId" :formatter="apiIdFormat" width="100">
<template slot-scope="scope">
{{ apiIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column
label="脚本批次"
align="center"
prop="scriptNum"
:show-overflow-tooltip="true"
/><el-table-column
label="脚本参数"
align="center"
prop="scriptParams"
:show-overflow-tooltip="true"
/><el-table-column
label="执行状态"
align="center"
prop="status"
:show-overflow-tooltip="true"
>
<template #default="{row}">
<el-tag size="mini" :type="['info','default','danger'][row.status]">{{ status[row.status] ? status[row.status].k : '未知' }}</el-tag>
</template>
</el-table-column>
<el-table-column
label="运行备注"
align="center"
prop="desc"
:show-overflow-tooltip="true"
/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:linePreScript:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:linePreScript:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="api用户" prop="apiId">
<el-select
v-model="form.apiId"
style="width: 100%;"
placeholder="请选择"
clearable
size="small"
>
<el-option
v-for="dict in apiIdOptions"
:key="dict.key"
:label="dict.value"
:value="Number(dict.key)"
/>
</el-select>
</el-form-item>
<el-form-item label="脚本批次" prop="scriptNum">
<el-input
v-model="form.scriptNum"
placeholder="脚本批次"
/>
</el-form-item>
<el-form-item label="脚本参数" prop="scriptParams">
<el-input
v-model="form.scriptParams"
placeholder="脚本参数"
/>
</el-form-item>
<el-form-item label="执行状态" prop="status">
<el-select
v-model="form.status"
placeholder="请选择"
style="width: 100%;"
>
<el-option
v-for="dict in status"
:key="dict.k"
:label="dict.k"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item label="运行备注" prop="desc">
<el-input
v-model="form.desc"
placeholder="运行备注"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLinePreScript, delLinePreScript, getLinePreScript, listLinePreScript, updateLinePreScript } from '@/api/admin/line-pre-script'
import { listLineApiUser } from '@/api/admin/line-api-user'
export default {
name: 'LinePreScript',
components: {
},
data() {
return {
// :0=等待执行,1=执行中,2=执行结束
status: [
{ k: '等待执行', v: '0' },
{ k: '执行中', v: '1' },
{ k: '执行结束', v: '2' }
],
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
linePreScriptList: [],
// 关系表类型
apiIdOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
apiId: undefined,
status: undefined,
idOrder: 'desc'
},
// 表单参数
form: {
},
// 表单校验
rules: { apiId: [{ required: true, message: 'api用户不能为空', trigger: 'blur' }],
status: [{ required: true, message: '执行状态:0=等待执行,1=执行中,2=执行结束不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
this.getLineApiUserItems()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLinePreScript(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.linePreScriptList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
apiId: undefined,
scriptNum: undefined,
scriptParams: undefined,
status: undefined,
desc: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
apiIdFormat(row) {
return this.selectItemsLabel(this.apiIdOptions, row.apiId)
},
// 关系
getLineApiUserItems() {
this.getItems(listLineApiUser, undefined).then(res => {
this.apiIdOptions = this.setItems(res, 'id', 'apiName')
})
},
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加委托下单脚本记录表'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLinePreScript(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改委托下单脚本记录表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLinePreScript(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLinePreScript(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLinePreScript({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,379 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="交易对" prop="symbol"><el-input
v-model="queryParams.symbol"
placeholder="请输入交易对"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="类型" prop="type"><el-select
v-model="queryParams.type"
placeholder="请选择类型"
clearable
size="small"
>
<el-option
v-for="dict in [{l:'现货',v:'1'},{l:'合约',v:'2'}]"
:key="dict.k"
:label="dict.l"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item label="方向" prop="directionStatus"><el-select
v-model="queryParams.directionStatus"
placeholder="请选择方向"
clearable
size="small"
>
<el-option
v-for="dict in [{l:'涨',v:'1'},{l:'跌',v:'2'}]"
:key="dict.k"
:label="dict.l"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:linePriceLimit:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:linePriceLimit:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
v-permisaction="['admin:linePriceLimit:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="linePriceLimitList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="id"
align="center"
prop="id"
:show-overflow-tooltip="true"
/>
<el-table-column
label="交易对"
align="center"
prop="symbol"
:show-overflow-tooltip="true"
/><el-table-column
label="类型"
align="center"
prop="type"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['现货','合约'][row.type-1] }}</template>
</el-table-column>
<el-table-column
label="方向"
align="center"
prop="directionStatus"
:show-overflow-tooltip="true"
>
<template #default="{row}"><el-tag :type="['success','danger'][row.directionStatus-1]">{{ ['涨','跌'][row.directionStatus-1] }}</el-tag></template>
</el-table-column>
<el-table-column
label="幅度"
align="center"
prop="range"
:show-overflow-tooltip="true"
/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<!-- <el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:linePriceLimit:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm> -->
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:linePriceLimit:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="交易对" prop="symbol">
<el-input
v-model="form.symbol"
placeholder="交易对"
/>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio label="1">现货</el-radio>
<el-radio label="2">合约</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="方向" prop="directionStatus">
<el-radio-group v-model="form.directionStatus">
<el-radio label="1"></el-radio>
<el-radio label="2"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="幅度" prop="range">
<el-input
v-model="form.range"
placeholder="幅度"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLinePriceLimit, delLinePriceLimit, getLinePriceLimit, listLinePriceLimit, updateLinePriceLimit } from '@/api/admin/line-price-limit'
export default {
name: 'LinePriceLimit',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
linePriceLimitList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
symbol: undefined,
type: undefined,
directionStatus: undefined,
range: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: { symbol: [{ required: true, message: '交易对不能为空', trigger: 'blur' }],
type: [{ required: true, message: '类型:1=现货,2=合约不能为空', trigger: 'blur' }],
directionStatus: [{ required: true, message: '方向:1=涨,2=跌不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLinePriceLimit(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.linePriceLimitList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
symbol: undefined,
type: '1',
directionStatus: '1',
range: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加涨跌幅'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLinePriceLimit(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改涨跌幅'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLinePriceLimit(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLinePriceLimit(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLinePriceLimit({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,366 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineRecharge:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineRecharge:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineRecharge:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineRechargeList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineRecharge:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineRecharge:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="币种id" prop="coinId">
<el-input v-model="form.coinId" placeholder="币种id"
/>
</el-form-item>
<el-form-item label="用户Id" prop="userId">
<el-input v-model="form.userId" placeholder="用户Id"
/>
</el-form-item>
<el-form-item label="区块确认数" prop="confirms">
<el-input v-model="form.confirms" placeholder="区块确认数"
/>
</el-form-item>
<el-form-item label="类型1线上2内部" prop="tranType">
<el-input v-model="form.tranType" placeholder="类型1线上2内部"
/>
</el-form-item>
<el-form-item label="区块高度" prop="blockIndex">
<el-input v-model="form.blockIndex" placeholder="区块高度"
/>
</el-form-item>
<el-form-item label="数量" prop="amount">
<el-input v-model="form.amount" placeholder="数量"
/>
</el-form-item>
<el-form-item label="账户" prop="account">
<el-input v-model="form.account" placeholder="账户"
/>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="form.address" placeholder="地址"
/>
</el-form-item>
<el-form-item label="交易id" prop="txid">
<el-input v-model="form.txid" placeholder="交易id"
/>
</el-form-item>
<el-form-item label="同步时间" prop="blockTime">
<el-date-picker
v-model="form.blockTime"
type="datetime"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
<el-form-item label="确认时间" prop="timeReceived">
<el-date-picker
v-model="form.timeReceived"
type="datetime"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
<el-form-item label="充值网络" prop="mainCoin">
<el-input v-model="form.mainCoin" placeholder="充值网络"
/>
</el-form-item>
<el-form-item label="订单号" prop="orderNo">
<el-input v-model="form.orderNo" placeholder="订单号"
/>
</el-form-item>
<el-form-item label="状态1==进行中暂时保留2==成功3==失败" prop="status">
<el-input v-model="form.status" placeholder="状态1==进行中暂时保留2==成功3==失败"
/>
</el-form-item>
<el-form-item label="来源状态 0 待審核 1 審核成功 2 審核駁回 3交易成功 4交易失敗" prop="state">
<el-input v-model="form.state" placeholder="来源状态 0 待審核 1 審核成功 2 審核駁回 3交易成功 4交易失敗"
/>
</el-form-item>
<el-form-item label="手续费" prop="fee">
<el-input v-model="form.fee" placeholder="手续费"
/>
</el-form-item>
<el-form-item label="来源地址" prop="addressFrom">
<el-input v-model="form.addressFrom" placeholder="来源地址"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineRecharge, delLineRecharge, getLineRecharge, listLineRecharge, updateLineRecharge} from '@/api/admin/line-recharge'
export default {
name: 'LineRecharge',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineRechargeList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineRecharge(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineRechargeList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
coinId: undefined,
userId: undefined,
confirms: undefined,
tranType: undefined,
blockIndex: undefined,
amount: undefined,
account: undefined,
address: undefined,
txid: undefined,
blockTime: undefined,
timeReceived: undefined,
mainCoin: undefined,
orderNo: undefined,
status: undefined,
state: undefined,
fee: undefined,
addressFrom: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加充值记录表'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineRecharge(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改充值记录表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineRecharge(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineRecharge(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineRecharge( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,343 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="交易对" prop="symbol"><el-input
v-model="queryParams.symbol"
placeholder="请输入交易对"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="类型" prop="type"><el-select
v-model="queryParams.type"
placeholder="请选择类型"
clearable
size="small"
>
<el-option
v-for="dict in [{l:'现货',v:'1'},{l:'合约',v:'2'}]"
:key="dict.k"
:label="dict.l"
:value="dict.v"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbolBlack:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbolBlack:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbolBlack:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineSymbolBlackList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="id"
align="center"
prop="id"
:show-overflow-tooltip="true"
/>
<el-table-column
label="交易对"
align="center"
prop="symbol"
:show-overflow-tooltip="true"
/><el-table-column
label="类型"
align="center"
prop="type"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ ['现货','合约'][row.type-1] }}</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineSymbolBlack:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineSymbolBlack:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="交易对" prop="symbol">
<el-input
v-model="form.symbol"
placeholder="交易对"
/>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio label="1">现货</el-radio>
<el-radio label="2">合约</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="btnLoading" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLineSymbolBlack, delLineSymbolBlack, getLineSymbolBlack, listLineSymbolBlack, updateLineSymbolBlack } from '@/api/admin/line-symbol-black'
export default {
name: 'LineSymbolBlack',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineSymbolBlackList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
symbol: undefined,
type: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: { symbol: [{ required: true, message: '交易对不能为空', trigger: 'blur' }],
type: [{ required: true, message: '类型:1=现货,2=合约不能为空', trigger: 'blur' }]
},
btnLoading: false
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineSymbolBlack(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineSymbolBlackList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
symbol: undefined,
type: '1'
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加交易对黑名单'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineSymbolBlack(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改交易对黑名单'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
this.btnLoading = true
updateLineSymbolBlack({ ...this.form, symbol: this.form.symbol.toUpperCase() }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).finally(() => {
this.btnLoading = false
})
} else {
this.btnLoading = true
addLineSymbolBlack({ ...this.form, symbol: this.form.symbol.toUpperCase() }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).finally(() => {
this.btnLoading = false
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.loading = true
return delLineSymbolBlack({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(() => {
this.loading = false
})
}
}
}
</script>

View File

@ -0,0 +1,401 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="90px">
<el-form-item label="交易对类型" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择交易对类型" clearable size="small">
<el-option v-for="dict in [{ label:'现货',value:'1'},{label:'合约',value:'2'}]" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbolGroup:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbolGroup:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbolGroup:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineSymbolGroupList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /><el-table-column
label="交易对组名称"
align="center"
prop="groupName"
:show-overflow-tooltip="true"
/><el-table-column
label="交易对"
align="center"
prop="symbol"
:show-overflow-tooltip="true"
/><el-table-column
label="类型"
align="center"
prop="type"
:show-overflow-tooltip="true"
>
<template #default="{row}">
{{ ['现货','合约'][row.type-1] || '' }}
</template>
</el-table-column>
<el-table-column label="数量" prop="count">
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineSymbolGroup:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineSymbolGroup:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="交易对组名称" prop="groupName">
<el-input
v-model="form.groupName"
placeholder="交易对组名称"
/>
</el-form-item>
<!-- <el-form-item label="分组类型:1=普通类型" prop="groupType">
<el-input v-model="form.groupType" placeholder="分组类型:1=普通类型"
/>
</el-form-item> -->
<el-form-item label="类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio label="1">现货</el-radio>
<el-radio label="2">合约</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="交易对" prop="symbol">
<el-select
v-model="form.symbol"
style="width: 100%;"
placeholder="请选择"
multiple
clearable
filterable
:remote-method="getSymbol"
:loading="searchLoding"
remote
size="small"
>
<el-option
v-for="dict in symbol.symbolList"
:key="dict.id"
:label="dict.symbol"
:value="dict.symbol"
/>
<div class="page">
<pagination
v-show="symbol.total>0"
:background="false"
:total="symbol.total"
layout="prev, pager, next"
:page.sync="symbol.pageIndex"
:limit.sync="symbol.pageSize"
@pagination="getSymbol"
/>
</div>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listLineSymbol } from '@/api/admin/line-symbol'
import { addLineSymbolGroup, delLineSymbolGroup, getLineSymbolGroup, listLineSymbolGroup, updateLineSymbolGroup } from '@/api/admin/line-symbol-group'
export default {
name: 'LineSymbolGroup',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineSymbolGroupList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
type: undefined,
idOrder:"desc"
},
// 表单参数
form: {
},
// 表单校验
rules: { type: [{ required: true, message: '类型:1=现货,2=合约不能为空', trigger: 'blur' }]
},
symbol: {
symbolList: [],
total: 0,
pageIndex: 1,
pageSize: 6
},
searchLoding: false
}
},
watch: {
'form.type'() {
this.form.symbol = undefined
this.getSymbol({})
}
},
created() {
this.getList()
},
methods: {
// 交易对列表
getSymbol(e, type) {
this.searchLoding = true
const { pageIndex } = this.symbol
const symbol = typeof e === 'object' ? '' : e
listLineSymbol({ pageIndex, pageSize: 6, type: type || this.form.type, symbol }).then(res => {
this.symbol.total = res.data.count
this.symbol.symbolList = res.data.list
}).finally(() => {
this.searchLoding = false
})
},
/** 查询参数列表 */
getList() {
this.loading = true
listLineSymbolGroup(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineSymbolGroupList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
groupName: undefined,
symbol: undefined,
groupType: '1',
type: '1'
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加交易对组列表'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineSymbolGroup(id).then(response => {
this.form = response.data
this.form.symbol = response.data.symbol ? response.data.symbol.split(',') : undefined
this.getSymbol()
this.open = true
this.title = '修改交易对组列表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineSymbolGroup({ ...this.form, symbol: this.form.symbol.toString() }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineSymbolGroup({ ...this.form, symbol: this.form.symbol.toString() }).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineSymbolGroup({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>
<style lang="scss" scoped>
.page{
.pagination-container{
padding: 0 !important;
margin-top: 0;
margin-bottom: 0;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
::v-deep.el-pagination{
width: 100%;
}
}
</style>

View File

@ -0,0 +1,432 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="90px" label-position="left">
<el-form-item label="交易对" prop="symbol"><el-input
v-model="queryParams.symbol"
placeholder="请输入交易对"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="基础货币" prop="baseAsset"><el-input
v-model="queryParams.baseAsset"
placeholder="请输入基础货币"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="计价货币" prop="quoteAsset"><el-input
v-model="queryParams.quoteAsset"
placeholder="请输入计价货币"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="交易对类型" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择交易对类型" clearable size="small">
<el-option v-for="dict in [{ label:'现货',value:'1'},{label:'合约',value:'2'}]" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbol:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbol:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineSymbol:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineSymbolList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /><el-table-column
label="交易对"
align="center"
prop="symbol"
:show-overflow-tooltip="true"
/><el-table-column
label="基础货币"
align="center"
prop="baseAsset"
:show-overflow-tooltip="true"
/><el-table-column
label="计价货币"
align="center"
prop="quoteAsset"
:show-overflow-tooltip="true"
/>
<el-table-column
label="状态"
align="center"
prop="switch"
:show-overflow-tooltip="true"
>
<template #default="{row}"><el-tag size="mini" :type="['danger','success'][row.switch]">{{ ['已关闭','已开启'][row.switch] }}</el-tag></template>
</el-table-column>
<el-table-column
label="交易对类型"
align="center"
prop="type"
:show-overflow-tooltip="true"
>
<template #default="{row}">
{{ ['现货','合约'][row.type-1] || '' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineSymbol:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineSymbol:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="api账户id" prop="apiId">
<el-input
v-model="form.apiId"
placeholder="api账户id"
/>
</el-form-item>
<el-form-item label="交易对" prop="symbol">
<el-input
v-model="form.symbol"
placeholder="交易对"
/>
</el-form-item>
<el-form-item label="基础货币" prop="baseAsset">
<el-input
v-model="form.baseAsset"
placeholder="基础货币"
/>
</el-form-item>
<el-form-item label="计价货币" prop="quoteAsset">
<el-input
v-model="form.quoteAsset"
placeholder="计价货币"
/>
</el-form-item>
<el-form-item label="状态" prop="switch">
<el-switch
v-model="form.switch"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="开启"
inactive-text="关闭"
active-value="1"
inactive-value="0"
/>
</el-form-item>
<el-form-item label="交易对类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio label="1">现货</el-radio>
<el-radio label="2">合约</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLineSymbol, delLineSymbol, getLineSymbol, listLineSymbol, updateLineSymbol } from '@/api/admin/line-symbol'
export default {
name: 'LineSymbol',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineSymbolList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
symbol: undefined,
baseAsset: undefined,
quoteAsset: undefined,
type: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: { symbol: [{ required: true, message: '交易对不能为空', trigger: 'blur' }],
baseAsset: [{ required: true, message: '基础货币不能为空', trigger: 'blur' }],
quoteAsset: [{ required: true, message: '计价货币不能为空', trigger: 'blur' }],
type: [{ required: true, message: '交易对类型不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
},
methods: {
// 获取杠杆api用户
// getListLineApiUser(){
// listLineApiUser({pageIndex:1,pageSize:999}).then(response => {
// this.lineUsers = response.data.list
// this.lineTotal = response.data.count
// })
// },
// 交易对列表
getSymbol(type) {
const { pageIndex } = this.symbol
listLineSymbol({ pageIndex, pageSize: 6, type: type || this.form.order_type }).then(res => {
this.symbol.total = res.data.count
this.symbol.symbolList = res.data.list
})
},
// 获取交易对组
// getSymbolGroup() {
// listLineSymbolGroup({ pageIndex:1, pageSize: 999,beginTime:undefined,endTime:undefined}).then(res => {
// this.symbolGroups = res.data.list
// })
// },
onCalc() {
if (!this.inForm.price || !this.percenter) {
return 0
}
let res
if (this.inForm.site === 'BUY') {
res = (1 - (this.percenter / 100)) * Number(this.inForm.price)
} else {
res = (1 + (this.percenter / 100)) * Number(this.inForm.price)
}
const [num, decimal] = String(res).split('.')
console.log(num, decimal, '?')
if (decimal) {
this.inForm.price = decimal.length > 4 ? `${num}.${decimal.substring(0, 4)}` : res
} else {
this.form.price = res
}
},
/** 查询参数列表 */
getList() {
this.loading = true
listLineSymbol(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineSymbolList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
apiId: undefined,
symbol: undefined,
baseAsset: undefined,
quoteAsset: undefined,
switch: '1',
type: '1'
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加交易对管理'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineSymbol(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改交易对管理'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineSymbol(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineSymbol(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineSymbol({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,285 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-table ref="table" v-loading="loading" :data="linePreOrderList">
<el-table-column
label="副账号限价对冲溢价买入百分比"
align="center"
prop="coverOrderTypeBRate"
width="210"
:show-overflow-tooltip="true"
/>
<el-table-column
label="主账号加仓溢价百分比"
align="center"
prop="scaleOrderTypeARate"
width="210"
:show-overflow-tooltip="true"
/>
<el-table-column
label="副账号加仓溢价百分比"
align="center"
prop="scaleOrderTypeBRate"
width="210"
:show-overflow-tooltip="true"
/>
<el-table-column
label="主单亏损多少百分比开始加仓"
align="center"
prop="scaleUnrealizedProfitRate"
width="210"
:show-overflow-tooltip="true"
/>
<el-table-column
label="加仓类型"
align="center"
prop="scaleType"
:show-overflow-tooltip="true"
>
<template #default="{row}">
<el-tag size="mini" :type="row.scaleType===1?'success':'default'">{{ ['','百分比','数值'][row.scaleType] }}</el-tag>
</template>
</el-table-column>
<el-table-column
label="加仓数值"
align="center"
prop="scaleNum"
:show-overflow-tooltip="true"
/>
<el-table-column
label="自动加仓次数"
align="center"
prop="autoScaleTimes"
width="100"
:show-overflow-tooltip="true"
/>
<el-table-column
label="加仓账户类型"
align="center"
width="100"
prop="scaleSubordinate"
:show-overflow-tooltip="true"
>
<template #default="{row}">
{{ ['主账号','副账号','都加'][row.scaleSubordinate-1] }}
</template>
</el-table-column>
<el-table-column
label="对冲平仓涨跌幅"
align="center"
prop="hedgePerformance"
width="200"
:show-overflow-tooltip="true"
/>
<el-table-column
label="对冲市价百分比"
align="center"
prop="protectHedgeRate"
width="80"
/>
<el-table-column
label="创建时间"
align="center"
prop="createdAt"
width="150"
:show-overflow-tooltip="true"
>
<template #default="{row}">{{ parseTime(row.createdAt) }}</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120" fixed="right">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<!-- <el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:linePreOrder:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm> -->
</template>
</el-table-column>
</el-table>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="700px">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" style="height: 600px;overflow: hidden auto;">
<el-form-item label="副账号限价对冲溢价买入百分比" prop="coverOrderTypeBRate">
<el-input v-model="form.coverOrderTypeBRate" placeholder="副账号限价对冲溢价买入百分比" />
</el-form-item>
<el-form-item label="主账号加仓溢价百分比" prop="scaleOrderTypeARate">
<el-input v-model="form.scaleOrderTypeARate" placeholder="主账号限价加仓买入百分比" />
</el-form-item>
<el-form-item label="副账号加仓溢价百分比" prop="scaleOrderTypeBRate">
<el-input v-model="form.scaleOrderTypeBRate" placeholder="副账号限价加仓买入百分比" />
</el-form-item>
<el-form-item label="主单亏损多少百分比开始加仓" prop="scaleUnrealizedProfitRate">
<el-input v-model="form.scaleUnrealizedProfitRate" placeholder="主单亏损多少百分比开始加仓" />
</el-form-item>
<el-form-item label="加仓类型" prop="scaleType">
<el-radio-group v-model="form.scaleType">
<el-radio :label="1">百分比</el-radio>
<el-radio :label="2">数值</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="加仓数值" prop="scaleNum">
<el-input v-model="form.scaleNum" placeholder="加仓数值" />
</el-form-item>
<el-form-item label="自动加仓次数" prop="autoScaleTimes">
<el-input v-model.number="form.autoScaleTimes" placeholder="自动加仓次数" type="number" />
</el-form-item>
<el-form-item label="对冲平仓涨跌幅" prop="hedgePerformance">
<el-input v-model="form.hedgePerformance" placeholder="对冲平仓涨跌幅" />
</el-form-item>
<el-form-item label="对冲市价亏损百分比" prop="protectHedgeRate">
<el-input v-model="form.protectHedgeRate" placeholder="对冲市价亏损百分比" />
</el-form-item>
<el-form-item label="只开启保险对冲" prop="protectHedgeEnable">
<el-radio-group v-model="form.protectHedgeEnable" lab>
<el-radio :label="0">关闭</el-radio>
<el-radio :label="1">开启</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="加仓账户类型" prop="scaleSubordinate">
<el-radio-group v-model="form.scaleSubordinate">
<el-radio :label="1">主账号</el-radio>
<el-radio :label="2">副账号</el-radio>
<el-radio :label="3">都加</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { systemSetting, systemSettingPut } from '@/api/admin/line-api-setting'
export default {
data() {
return {
// 遮罩层
loading: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
linePreOrderList: [],
// 表单参数
form: {
},
// 表单校验
rules: {
scaleOrderTypeARate: [{ required: true, message: '主账号限价加仓买入百分比不能为空', trigger: 'blur' }],
scaleOrderTypeBRate: [{ required: true, message: '副账号限价加仓买入百分比不能为空', trigger: 'blur' }],
coverOrderTypeBRate: [{ required: true, message: '副账号限价对冲单价买入百分比不能为空', trigger: 'blur' }],
scaleNum: [{ required: true, message: '加参数值不能为空', trigger: 'blur' }],
autoScaleTimes: [{ required: true, message: '自动加仓次数不能为空', trigger: 'blur' }],
scaleUnrealizedProfitRate: [{ required: true, message: '主单亏损多少百分比开始加仓不能为空', trigger: 'blur' }],
hedgePerformance: [{ required: true, message: '对冲平仓涨跌幅不能为空', trigger: 'blur' }],
scaleSubordinate: [{ required: true, message: '自动加仓数值不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
systemSetting().then(response => {
this.linePreOrderList = response.data.list
this.loading = false
})
},
// 取消按钮
cancel() {
this.open = false
this.resetForm('form')
},
/** 修改按钮操作 */
handleUpdate(row) {
this.title = '修改挂单配置'
this.form = row
this.open = true
this.isEdit = true
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
systemSettingPut(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.hour{
::v-deep.el-input__inner{
line-height: 1;
}
}
.page{
.pagination-container{
padding: 0 !important;
margin-top: 0;
margin-bottom: 0;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
::v-deep.el-pagination{
width: 100%;
}
}
</style>

View File

@ -0,0 +1,320 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUduncoin:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUduncoin:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUduncoin:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineUduncoinList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUduncoin:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUduncoin:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="0 主幣 1代幣" prop="tokenStatus">
<el-input v-model="form.tokenStatus" placeholder="0 主幣 1代幣"
/>
</el-form-item>
<el-form-item label="幣種精度,8" prop="decimals">
<el-input v-model="form.decimals" placeholder="幣種精度,8"
/>
</el-form-item>
<el-form-item label="主幣種類型" prop="mainCoinType">
<el-input v-model="form.mainCoinType" placeholder="主幣種類型"
/>
</el-form-item>
<el-form-item label="幣種類型" prop="coinType">
<el-input v-model="form.coinType" placeholder="幣種類型"
/>
</el-form-item>
<el-form-item label="幣種symbol" prop="symbol">
<el-input v-model="form.symbol" placeholder="幣種symbol"
/>
</el-form-item>
<el-form-item label="幣種別名,BTC" prop="name">
<el-input v-model="form.name" placeholder="幣種別名,BTC"
/>
</el-form-item>
<el-form-item label="幣種logo地址" prop="logo">
<el-input v-model="form.logo" placeholder="幣種logo地址"
/>
</el-form-item>
<el-form-item label="幣種全稱,Bitcoin" prop="coinName">
<el-input v-model="form.coinName" placeholder="幣種全稱,Bitcoin"
/>
</el-form-item>
<el-form-item label="主幣種symbol" prop="mainSymbol">
<el-input v-model="form.mainSymbol" placeholder="主幣種symbol"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineUduncoin, delLineUduncoin, getLineUduncoin, listLineUduncoin, updateLineUduncoin} from '@/api/admin/line-uduncoin'
export default {
name: 'LineUduncoin',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineUduncoinList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineUduncoin(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineUduncoinList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
tokenStatus: undefined,
decimals: undefined,
mainCoinType: undefined,
coinType: undefined,
symbol: undefined,
name: undefined,
logo: undefined,
coinName: undefined,
mainSymbol: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加【u盾支持的币种信息】'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineUduncoin(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改【u盾支持的币种信息】'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineUduncoin(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineUduncoin(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineUduncoin( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,285 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUserFundingTrend:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUserFundingTrend:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUserFundingTrend:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineUserFundingTrendList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUserFundingTrend:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUserFundingTrend:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户id" prop="userId">
<el-input v-model="form.userId" placeholder="用户id"
/>
</el-form-item>
<el-form-item label="资金账户总额 换算U" prop="funding">
<el-input v-model="form.funding" placeholder="资金账户总额 换算U"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineUserFundingTrend, delLineUserFundingTrend, getLineUserFundingTrend, listLineUserFundingTrend, updateLineUserFundingTrend} from '@/api/admin/line-user-funding-trend'
export default {
name: 'LineUserFundingTrend',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineUserFundingTrendList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineUserFundingTrend(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineUserFundingTrendList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
userId: undefined,
funding: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加用户资金走势'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineUserFundingTrend(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改用户资金走势'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineUserFundingTrend(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineUserFundingTrend(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineUserFundingTrend( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,399 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="line_user 表的id" prop="userId"><el-select v-model="queryParams.userId"
placeholder="请选择" clearable size="small" >
<el-option
v-for="dict in userIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-form-item>
<el-form-item label="line_apiuser 表的id" prop="apiId"><el-select v-model="queryParams.apiId"
placeholder="请选择" clearable size="small" >
<el-option
v-for="dict in apiIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-form-item>
<el-form-item label="line_pre_order 主订单id" prop="preOrderId"><el-select v-model="queryParams.preOrderId"
placeholder="请选择" clearable size="small" >
<el-option
v-for="dict in preOrderIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-form-item>
<el-form-item label="成交数量" prop="num"><el-input v-model="queryParams.num" placeholder="请输入成交数量" clearable
size="small" @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="交易对" prop="symbol"><el-input v-model="queryParams.symbol" placeholder="请输入交易对" clearable
size="small" @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUserProfitLogs:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUserProfitLogs:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUserProfitLogs:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineUserProfitLogsList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/><el-table-column label="line_user 表的id" align="center" prop="userId" :formatter="userIdFormat" width="100">
<template slot-scope="scope">
{{ userIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column label="line_apiuser 表的id" align="center" prop="apiId" :formatter="apiIdFormat" width="100">
<template slot-scope="scope">
{{ apiIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column label="line_pre_order 主订单id" align="center" prop="preOrderId" :formatter="preOrderIdFormat" width="100">
<template slot-scope="scope">
{{ preOrderIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column label="成交数量" align="center" prop="num"
:show-overflow-tooltip="true"/><el-table-column label="交易对" align="center" prop="symbol"
:show-overflow-tooltip="true"/><el-table-column label="盈利比例" align="center" prop="rate"
:show-overflow-tooltip="true"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUserProfitLogs:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUserProfitLogs:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="line_user 表的id" prop="userId">
<el-input v-model="form.userId" placeholder="line_user 表的id"
/>
</el-form-item>
<el-form-item label="line_apiuser 表的id" prop="apiId">
<el-input v-model="form.apiId" placeholder="line_apiuser 表的id"
/>
</el-form-item>
<el-form-item label="line_pre_order 主订单id" prop="preOrderId">
<el-input v-model="form.preOrderId" placeholder="line_pre_order 主订单id"
/>
</el-form-item>
<el-form-item label="成交数量" prop="num">
<el-input v-model="form.num" placeholder="成交数量"
/>
</el-form-item>
<el-form-item label="交易对" prop="symbol">
<el-input v-model="form.symbol" placeholder="交易对"
/>
</el-form-item>
<el-form-item label="盈利比例" prop="rate">
<el-input v-model="form.rate" placeholder="盈利比例"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineUserProfitLogs, delLineUserProfitLogs, getLineUserProfitLogs, listLineUserProfitLogs, updateLineUserProfitLogs} from '@/api/admin/line-user-profit-logs'
import {listLineUser } from '@/api/admin/line-user'
import {listLineApiUser } from '@/api/admin/line-api-user'
import {listLinePreOrder } from '@/api/admin/line-pre-order'
export default {
name: 'LineUserProfitLogs',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineUserProfitLogsList: [],
// 关系表类型
userIdOptions :[],
apiIdOptions :[],
preOrderIdOptions :[],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
userId:undefined,
apiId:undefined,
preOrderId:undefined,
num:undefined,
symbol:undefined,
},
// 表单参数
form: {
},
// 表单校验
rules: {userId: [ {required: true, message: 'line_user 表的id不能为空', trigger: 'blur'} ],
apiId: [ {required: true, message: 'line_apiuser 表的id不能为空', trigger: 'blur'} ],
preOrderId: [ {required: true, message: 'line_pre_order 主订单id不能为空', trigger: 'blur'} ],
num: [ {required: true, message: '成交数量不能为空', trigger: 'blur'} ],
symbol: [ {required: true, message: '交易对不能为空', trigger: 'blur'} ],
}
}
},
created() {
this.getList()
this.getLineUserItems()
this.getLineApiUserItems()
this.getLinePreOrderItems()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineUserProfitLogs(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineUserProfitLogsList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
userId: undefined,
apiId: undefined,
preOrderId: undefined,
num: undefined,
symbol: undefined,
rate: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
userIdFormat(row) {
return this.selectItemsLabel(this.userIdOptions, row.userId)
},
apiIdFormat(row) {
return this.selectItemsLabel(this.apiIdOptions, row.apiId)
},
preOrderIdFormat(row) {
return this.selectItemsLabel(this.preOrderIdOptions, row.preOrderId)
},
// 关系
getLineUserItems() {
this.getItems(listLineUser, undefined).then(res => {
this.userIdOptions = this.setItems(res, 'id', 'username')
})
},
getLineApiUserItems() {
this.getItems(listLineApiUser, undefined).then(res => {
this.apiIdOptions = this.setItems(res, 'id', 'apiName')
})
},
getLinePreOrderItems() {
this.getItems(listLinePreOrder, undefined).then(res => {
this.preOrderIdOptions = this.setItems(res, 'id', 'orderSn')
})
},
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加会员盈利记录表'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineUserProfitLogs(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改会员盈利记录表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineUserProfitLogs(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineUserProfitLogs(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineUserProfitLogs( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,449 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUser:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUser:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineUser:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineUserList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="用户名" prop="username" align="center" />
<el-table-column label="手机号" prop="mobile" align="center" />
<el-table-column label="保证金" prop="money" align="center" />
<el-table-column label="邮箱" prop="email" align="center" />
<el-table-column label="状态" prop="status" align="center">
<template #default="{row}">
<el-tag size="mini" :type="row.status==='normal'?'success':'danger'">{{ {normal:'正常',verify:'未验证'}[row.status] || '未知' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="启动状态" prop="open_status" align="center">
<template #default="{row}">
<el-tag size="mini" :type="row.open_status?'success':'danger'">{{ ['停止','启动'][row.open_status] || '未知' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUser:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineUser:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- <el-form-item label="用户名" prop="username">
<el-input
v-model="form.username"
placeholder="用户名"
/>
</el-form-item>
<el-form-item label="昵称" prop="nickname">
<el-input
v-model="form.nickname"
placeholder="昵称"
/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="form.password"
placeholder="密码"
/>
</el-form-item>
<el-form-item label="密码盐" prop="salt">
<el-input
v-model="form.salt"
placeholder="密码盐"
/>
</el-form-item>
<el-form-item label="电子邮箱" prop="email">
<el-input
v-model="form.email"
placeholder="电子邮箱"
/>
</el-form-item>
<el-form-item label="手机号" prop="mobile">
<el-input
v-model="form.mobile"
placeholder="手机号"
/>
</el-form-item>
<el-form-item label="头像" prop="avatar">
<el-input
v-model="form.avatar"
placeholder="头像"
/>
</el-form-item>
<el-form-item label="等级" prop="level">
<el-input
v-model="form.level"
placeholder="等级"
/>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-input
v-model="form.gender"
placeholder="性别"
/>
</el-form-item>
<el-form-item label="生日" prop="birthday">
<el-input
v-model="form.birthday"
placeholder="生日"
/>
</el-form-item>
<el-form-item label="格言" prop="bio">
<el-input
v-model="form.bio"
placeholder="格言"
/>
</el-form-item> -->
<el-form-item label="保证金" prop="money">
<el-input
v-model="form.money"
placeholder="保证金"
/>
</el-form-item>
<!-- <el-form-item label="积分" prop="score">
<el-input
v-model="form.score"
placeholder="积分"
/>
</el-form-item>
<el-form-item label="连续登录天数" prop="successions">
<el-input
v-model="form.successions"
placeholder="连续登录天数"
/>
</el-form-item>
<el-form-item label="最大连续登录天数" prop="maxSuccessions">
<el-input
v-model="form.maxSuccessions"
placeholder="最大连续登录天数"
/>
</el-form-item>
<el-form-item label="登录IP" prop="loginip">
<el-input
v-model="form.loginip"
placeholder="登录IP"
/>
</el-form-item>
<el-form-item label="失败次数" prop="loginfailure">
<el-input
v-model="form.loginfailure"
placeholder="失败次数"
/>
</el-form-item>
<el-form-item label="加入IP" prop="joinip">
<el-input
v-model="form.joinip"
placeholder="加入IP"
/>
</el-form-item>
<el-form-item label="加入时间" prop="jointime">
<el-input
v-model="form.jointime"
placeholder="加入时间"
/>
</el-form-item>
<el-form-item label="Token" prop="token">
<el-input
v-model="form.token"
placeholder="Token"
/>
</el-form-item> -->
<el-form-item label="启动状态" prop="open_status">
<el-radio-group v-model="form.open_status">
<el-radio :label="1">启动</el-radio>
<el-radio :label="0">停止</el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="验证" prop="verification">
<el-input
v-model="form.verification"
placeholder="验证"
/>
</el-form-item>
<el-form-item label="登录时间" prop="loginTime">
<el-date-picker
v-model="form.loginTime"
type="datetime"
placeholder="选择日期"
/>
</el-form-item> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addLineUser, delLineUser, getLineUser, listLineUser, updateLineUser } from '@/api/admin/line-user'
export default {
name: 'LineUser',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineUserList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineUserList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
groupId: undefined,
username: undefined,
nickname: undefined,
password: undefined,
salt: undefined,
email: undefined,
mobile: undefined,
avatar: undefined,
level: undefined,
gender: undefined,
birthday: undefined,
bio: undefined,
money: undefined,
score: undefined,
successions: undefined,
maxSuccessions: undefined,
loginip: undefined,
loginfailure: undefined,
joinip: undefined,
jointime: undefined,
token: undefined,
status: undefined,
verification: undefined,
loginTime: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加会员表'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineUser(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改会员表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineUser(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineUser(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delLineUser({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,300 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineWallet:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineWallet:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:lineWallet:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="lineWalletList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineWallet:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:lineWallet:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户Id" prop="userId">
<el-input v-model="form.userId" placeholder="用户Id"
/>
</el-form-item>
<el-form-item label="币种id" prop="coinId">
<el-input v-model="form.coinId" placeholder="币种id"
/>
</el-form-item>
<el-form-item label="标签" prop="tag">
<el-input v-model="form.tag" placeholder="标签"
/>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="form.address" placeholder="地址"
/>
</el-form-item>
<el-form-item label="币种主网iduseri+主网id做唯一" prop="coinNetworkId">
<el-input v-model="form.coinNetworkId" placeholder="币种主网iduseri+主网id做唯一"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {addLineWallet, delLineWallet, getLineWallet, listLineWallet, updateLineWallet} from '@/api/admin/line-wallet'
export default {
name: 'LineWallet',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
lineWalletList: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
},
// 表单参数
form: {
},
// 表单校验
rules: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listLineWallet(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.lineWalletList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
userId: undefined,
coinId: undefined,
tag: undefined,
address: undefined,
coinNetworkId: undefined,
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加用户钱包地址'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getLineWallet(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改用户钱包地址'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateLineWallet(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addLineWallet(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
return delLineWallet( { 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function () {
})
}
}
}
</script>

View File

@ -0,0 +1,430 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="48px">
<el-form-item label="标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入标题"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="地址" prop="path">
<el-input
v-model="queryParams.path"
placeholder="请输入地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="Method" prop="action">
<el-select
v-model="queryParams.action"
placeholder="请选择Method"
clearable
size="small"
@keyup.enter.native="handleQuery"
>
<el-option value="GET">GET</el-option>
<el-option value="POST">POST</el-option>
<el-option value="PUT">PUT</el-option>
<el-option value="DELETE">DELETE</el-option>
</el-select>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select
v-model="queryParams.type"
placeholder="请选择类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
>
<el-option value="SYS">SYS</el-option>
<el-option value="BUS">BUS</el-option>
<el-option value="暂无">暂无</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="sysapiList"
border
@selection-change="handleSelectionChange"
@sort-change="handleSortChang"
>
<el-table-column
label="标题"
header-align="center"
align="left"
prop="title"
fixed="left"
sortable="custom"
width="260px"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<span v-if="scope.row.type=='SYS' && scope.row.title!=''"><el-tag type="success">{{ '['+scope.row.type +'] '+ scope.row.title }}</el-tag></span>
<span v-if="scope.row.type!='SYS' && scope.row.title!=''"><el-tag type="">{{ '['+scope.row.type +'] '+scope.row.title }}</el-tag></span>
<span v-if="scope.row.title==''"><el-tag type="danger">暂无</el-tag></span>
</template>
</el-table-column>
<el-table-column
label="Request Info"
header-align="center"
align="left"
prop="path"
sortable="custom"
:show-overflow-tooltip="true"
>
<!-- <template slot-scope="scope">
<span>{{ "["+scope.row.action +"] "+ scope.row.path }}</span>
</template> -->
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p><span v-if="scope.row.type=='SYS' && scope.row.title!=''"><el-tag type="success">{{ '['+scope.row.type +'] '+ scope.row.title }}</el-tag></span>
<span v-if="scope.row.type!='SYS' && scope.row.title!=''"><el-tag type="">{{ '['+scope.row.type +'] '+scope.row.title }}</el-tag></span>
<span v-if="scope.row.title==''"><el-tag type="danger">暂无</el-tag></span>
</p>
<p>Handle: {{ scope.row.handle }}</p>
<p>Method:
<el-tag v-if="scope.row.action=='GET'">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='POST'" type="success">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='PUT'" type="warning">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='DELETE'" type="danger">{{ scope.row.action }}</el-tag>
</p>
<p>接口类型: {{ scope.row.type }}</p>
<div slot="reference" class="name-wrapper">
<el-tag v-if="scope.row.action=='GET'">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='POST'" type="success">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='PUT'" type="warning">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='DELETE'" type="danger">{{ scope.row.action }}</el-tag>
{{ scope.row.path }}
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createdAt"
width="155px"
sortable="custom"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="80px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysApi:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-drawer
ref="drawer"
:title="title"
:before-close="cancel"
:visible.sync="open"
direction="rtl"
custom-class="demo-drawer"
>
<div class="demo-drawer__content">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="Handle" prop="handle">
<el-input
v-model="form.handle"
placeholder="handle"
/>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input
v-model="form.title"
placeholder="标题"
/>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select
v-model="form.type"
placeholder="请选择类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
>
<el-option value="SYS">SYS</el-option>
<el-option value="BUS">BUS</el-option>
</el-select>
</el-form-item>
<el-form-item label="Method" prop="action">
<el-select
v-model="form.action"
placeholder="请选择方式"
clearable
size="small"
@keyup.enter.native="handleQuery"
>
<el-option value="GET">GET</el-option>
<el-option value="POST">POST</el-option>
<el-option value="PUT">PUT</el-option>
<el-option value="DELETE">DELETE</el-option>
</el-select>
</el-form-item>
<el-form-item label="地址" prop="path">
<el-input
v-model="form.path"
:disabled="isEdit"
placeholder="地址"
/>
</el-form-item>
</el-form>
<div class="demo-drawer__footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</div>
</el-drawer>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addSysApi, delSysApi, getSysApi, listSysApi, updateSysApi } from '@/api/admin/sys-api'
export default {
name: 'SysApiManage',
components: {
},
data() {
return {
dialog: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
sysapiList: [],
dateRange: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
name: undefined,
title: undefined,
path: undefined,
type: undefined,
action: undefined,
parentId: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: {
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
path: [{ required: true, message: '地址不能为空', trigger: 'blur' }],
action: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
parentId: [{ required: true, message: '按钮id不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
},
methods: {
handleClose(done) {
if (this.loading) {
return
}
done()
},
/** 查询参数列表 */
getList() {
this.loading = true
listSysApi(this.queryParams).then(response => {
this.sysapiList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
name: undefined,
title: undefined,
path: undefined,
paths: undefined,
action: undefined,
parentId: undefined,
sort: undefined
}
this.resetForm('form')
},
parentIdFormat(row) {
return this.selectItemsLabel(this.parentIdOptions, row.parentId)
},
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加接口管理'
this.isEdit = false
},
/** 排序回调函数 */
handleSortChang(column, prop, order) {
prop = column.prop
order = column.order
if (this.order !== '' && this.order !== prop + 'Order') {
this.queryParams[this.order] = undefined
}
if (order === 'descending') {
this.queryParams[prop + 'Order'] = 'desc'
this.order = prop + 'Order'
} else if (order === 'ascending') {
this.queryParams[prop + 'Order'] = 'asc'
this.order = prop + 'Order'
} else {
this.queryParams[prop + 'Order'] = undefined
}
this.getList()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getSysApi(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改接口管理'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateSysApi(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addSysApi(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delSysApi({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
}
}
}
</script>

View File

@ -0,0 +1,432 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="48px">
<el-form-item label="名称" prop="configName">
<el-input
v-model="queryParams.configName"
placeholder="请输入参数名称"
clearable
size="small"
style="width: 160px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="键名" prop="configKey">
<el-input
v-model="queryParams.configKey"
placeholder="请输入参数键名"
clearable
size="small"
style="width: 160px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="内置" prop="configType">
<el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small">
<el-option
v-for="dict in typeOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysConfig:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysConfig:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysConfig:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysConfig:export']"
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="configList"
border
@selection-change="handleSelectionChange"
@sort-change="handleSortChang"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="编码"
sortable="custom"
width="75"
prop="id"
/>
<el-table-column
label="名称"
sortable="custom"
prop="configName"
:show-overflow-tooltip="true"
/>
<el-table-column
label="键名"
sortable="custom"
prop="configKey"
>
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>键值: {{ scope.row.configValue }}</p>
<p>UI参数: <el-tag v-if="scope.row.isFrontend=='2'"></el-tag>
<el-tag v-if="scope.row.isFrontend=='1'" type="success"></el-tag>
</p>
<div slot="reference" class="name-wrapper">
{{ scope.row.configKey }}
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="内置"
sortable="custom"
prop="configType"
:formatter="typeFormat"
width="80"
/>
<el-table-column
label="备注"
prop="remark"
:show-overflow-tooltip="true"
/>
<el-table-column
label="创建时间"
sortable="custom"
prop="createdAt"
width="160"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
class-name="small-padding fixed-width"
width="120"
>
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysConfig:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysConfig:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="参数名称" prop="configName">
<el-input v-model="form.configName" placeholder="请输入参数名称" :disabled="isEdit" />
</el-form-item>
<el-form-item label="参数键名" prop="configKey">
<el-input v-model="form.configKey" placeholder="请输入参数键名" :disabled="isEdit" />
</el-form-item>
<el-form-item label="参数键值" prop="configValue">
<el-input v-model="form.configValue" placeholder="请输入参数键值" />
</el-form-item>
<el-form-item label="系统内置" prop="configType">
<el-radio-group v-model="form.configType">
<el-radio
v-for="dict in typeOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="前台显示" prop="isFrontend">
<el-select v-model="form.isFrontend" placeholder="是否前台显示" clearable size="small">
<el-option label="是" value="1" />
<el-option label="否" value="2" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listConfig, getConfig, delConfig, addConfig, updateConfig } from '@/api/admin/sys-config'
import { formatJson } from '@/utils'
export default {
name: 'SysConfigManage',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 参数表格数据
configList: [],
// 排序字段
order: 'createdAtOrder',
// 弹出层标题
title: '',
isEdit: false,
// 是否显示弹出层
open: false,
// 类型数据字典
typeOptions: [],
// 日期范围
dateRange: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
configName: undefined,
configKey: undefined,
configType: undefined,
createdAtOrder: 'desc'
},
// 表单参数
form: {},
// 表单校验
rules: {
configName: [{ required: true, message: '参数名称不能为空', trigger: 'blur' }],
configKey: [{ required: true, message: '参数键名不能为空', trigger: 'blur' }],
configValue: [{ required: true, message: '参数键值不能为空', trigger: 'blur' }],
isFrontend: [{ required: true, message: '是否前台显示不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
this.getDicts('sys_yes_no').then(response => {
this.typeOptions = response.data
})
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.configList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 参数系统内置字典翻译
typeFormat(row, column) {
return this.selectDictLabel(this.typeOptions, row.configType)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
configName: undefined,
configKey: undefined,
configValue: undefined,
configType: 'Y',
isFrontend: '1',
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.queryParams['createdAtOrderOrder'] = 'desc'
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加参数'
this.isEdit = false
},
handleSortChang(column, prop, order) {
prop = column.prop
order = column.order
if (this.order !== '' && this.order !== prop + 'Order') {
this.queryParams[this.order] = undefined
}
if (order === 'descending') {
this.queryParams[prop + 'Order'] = 'desc'
this.order = prop + 'Order'
} else if (order === 'ascending') {
this.queryParams[prop + 'Order'] = 'asc'
this.order = prop + 'Order'
} else {
this.queryParams[prop + 'Order'] = undefined
}
this.getList()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const ID = row.id || this.ids
getConfig(ID).then(response => {
this.form = response.data
this.open = true
this.title = '修改参数'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateConfig(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addConfig(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delConfig({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
// const queryParams = this.queryParams
this.$confirm('是否确认导出所有参数数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['参数主键', '参数名称', '参数键名', '参数键值', '备注', '创建时间']
const filterVal = ['configId', 'configName', 'configKey', 'configValue', 'remark', 'createdAt']
const list = this.configList
const data = formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: '参数设置',
autoWidth: true, // Optional
bookType: 'xlsx' // Optional
})
this.downloadLoading = false
})
})
}
}
}
</script>

View File

@ -0,0 +1,223 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-tabs tab-position="left" style="height: 100%;">
<el-tab-pane label="系统内置">
<el-form label-width="80px">
<div class="test-form">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="100px">
<el-form-item label="系统名称" prop="sys_app_name">
<el-input v-model="form.sys_app_name" placeholder="请输入系统名称" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="系统logo" prop="sys_app_logo" required>
<img v-if="form.sys_app_logo" :src="form.sys_app_logo" class="el-upload el-upload--picture-card" style="float:left">
<el-upload ref="sys_app_logo" :headers="headers" :file-list="sys_app_logofileList" :action="sys_app_logoAction" style="float:left" :before-upload="sys_app_logoBeforeUpload" list-type="picture-card" :show-file-list="false" :on-success="uploadSuccess">
<i class="el-icon-plus" />
</el-upload>
</el-form-item>
<el-form-item label="初始密码" prop="sys_user_initPassword">
<el-input v-model="form.sys_user_initPassword" placeholder="请输入初始密码" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="皮肤样式" prop="sys_index_skinName">
<el-select v-model="form.sys_index_skinName" placeholder="请选择皮肤样式" clearable :style="{width: '100%'}">
<el-option v-for="(item, index) in sys_index_skinNameOptions" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled" />
</el-select>
</el-form-item>
<el-form-item label="侧栏主题" prop="sys_index_sideTheme">
<el-select v-model="form.sys_index_sideTheme" placeholder="请选择侧栏主题" clearable :style="{width: '100%'}">
<el-option v-for="(item, index) in sys_index_sideThemeOptions" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled" />
</el-select>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</el-form>
</el-tab-pane>
<el-tab-pane label="其他">其他</el-tab-pane>
</el-tabs>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import {
getSetConfig,
updateSetConfig
} from '@/api/admin/sys-config'
import { getToken } from '@/utils/auth'
export default {
name: 'SysConfigSet',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 参数表格数据
configList: [],
formConf: {},
headers: { 'Authorization': 'Bearer ' + getToken() },
form: {
sys_app_name: undefined,
sys_app_logo: null,
sys_user_initPassword: undefined,
sys_index_skinName: undefined,
sys_index_sideTheme: undefined
},
rules: {
sys_app_name: [{
required: true,
message: '请输入系统名称',
trigger: 'blur'
}],
sys_user_initPassword: [{
required: true,
message: '请输入初始密码',
trigger: 'blur'
}],
sys_index_skinName: [{
required: true,
message: '请选择皮肤样式',
trigger: 'change'
}],
sys_index_sideTheme: [{
required: true,
message: '请选择侧栏主题',
trigger: 'change'
}]
},
sys_app_logoAction: process.env.VUE_APP_BASE_API + '/api/v1/public/uploadFile',
sys_app_logofileList: [],
sys_index_skinNameOptions: [{
'label': '蓝色',
'value': 'skin-blue'
}],
sys_index_sideThemeOptions: [{
'label': '深色主题',
'value': 'theme-dark'
}]
}
},
created() {
this.getList()
},
methods: {
submitForm() {
console.log(this.form)
this.$refs['form'].validate(valid => {
if (!valid) return
console.log(this.form)
var list = []
var i = 0
for (var key in this.form) {
list[i] = {
'configKey': key,
'configValue': this.form[key]
}
i++
}
updateSetConfig(list).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
const { sys_app_name, sys_app_logo } = this.form
this.$store.commit('system/SET_INFO', {
sys_app_logo,
sys_app_name
})
} else {
this.msgError(response.msg)
}
})
})
},
resetForm() {
this.$refs['form'].resetFields()
},
sys_app_logoBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 2
if (!isRightSize) {
this.$message.error('文件大小超过 2MB')
}
return isRightSize
},
uploadSuccess(response, file, fileList) {
console.log('sss')
this.form.sys_app_logo = process.env.VUE_APP_BASE_API + response.data.full_path
console.log(response.data.full_path)
},
/** 查询参数列表 */
getList() {
this.loading = true
getSetConfig().then(response => {
this.configList = response.data
this.loading = false
this.form = this.configList
// this.sys_app_logofileList = [this.configList.sys_app_logo]
// this.fillFormData(this.elForm, this.configList)
// 更新表单
// this.key2 = +new Date()
})
},
setUrl(url) {
const data = {
sys_app_logo: ''
}
data.sys_app_logo = url
// 回填数据
this.fillFormData(this.formConf, data)
// 更新表单
this.key2 = +new Date()
},
// 参数系统内置字典翻译
typeFormat(row, column) {
return this.selectDictLabel(this.typeOptions, row.configType)
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
fillFormData(form, data) {
form.fields.forEach(item => {
const val = data[item.__vModel__]
if (val) {
item.__config__.defaultValue = val
}
})
},
bind(key, data) {
this.setUrl(data)
},
sumbitForm2(data) {
var list = []
var i = 0
for (var key in data) {
list[i] = {
'configKey': key,
'configValue': data[key]
}
i++
}
updateSetConfig(list).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
}
</script>

View File

@ -0,0 +1,370 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form :inline="true">
<el-form-item label="部门名称">
<el-input
v-model="queryParams.deptName"
placeholder="请输入部门名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable size="small">
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button>
<el-button
v-permisaction="['admin:sysDept:add']"
class="filter-item"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="deptList"
row-key="deptId"
default-expand-all
border
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="deptName" label="部门名称" />
<el-table-column prop="sort" label="排序" width="200" />
<el-table-column prop="status" label="状态" :formatter="statusFormat" width="100">
<template slot-scope="scope">
<el-tag
:type="scope.row.status === 1 ? 'danger' : 'success'"
disable-transitions
>{{ statusFormat(scope.row) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdAt" width="200">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysDept:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysDept:add']"
size="mini"
type="text"
icon="el-icon-plus"
@click="handleAdd(scope.row)"
>新增</el-button>
<el-button
v-if="scope.row.p_id != 0"
v-permisaction="['admin:sysDept:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改部门对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="上级部门" prop="parentId">
<treeselect
v-model="form.parentId"
:options="deptOptions"
:normalizer="normalizer"
:show-count="true"
placeholder="选择上级部门"
:is-disabled="isEdit"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number v-model="form.sort" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="负责人" prop="leader">
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { getDeptList, getDept, delDept, addDept, updateDept } from '@/api/admin/sys-dept'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
name: 'SysDeptManage',
components: { Treeselect },
data() {
return {
// 遮罩层
loading: true,
// 表格树数据
deptList: [],
// 部门树选项
deptOptions: [],
// 弹出层标题
title: '',
isEdit: false,
// 是否显示弹出层
open: false,
// 状态数据字典
statusOptions: [],
// 查询参数
queryParams: {
deptName: undefined,
status: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: {
parentId: [
{ required: true, message: '上级部门不能为空', trigger: 'blur' }
],
deptName: [
{ required: true, message: '部门名称不能为空', trigger: 'blur' }
],
sort: [
{ required: true, message: '菜单顺序不能为空', trigger: 'blur' }
],
leader: [
{ required: true, message: '负责人不能为空', trigger: 'blur' }
],
email: [
{
type: 'email',
message: "'请输入正确的邮箱地址",
trigger: ['blur', 'change']
}
],
phone: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur'
}
]
}
}
},
created() {
this.getList()
this.getDicts('sys_normal_disable').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询部门列表 */
getList() {
this.loading = true
getDeptList(this.queryParams).then(response => {
this.deptList = response.data
this.loading = false
})
},
/** 转换部门数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.deptId,
label: node.deptName,
children: node.children
}
},
/** 查询部门下拉树结构 */
getTreeselect(e) {
getDeptList().then(response => {
this.deptOptions = []
if (e === 'update') {
const dept = { deptId: 0, deptName: '主类目', children: [], isDisabled: true }
dept.children = response.data
this.deptOptions.push(dept)
} else {
const dept = { deptId: 0, deptName: '主类目', children: [] }
dept.children = response.data
this.deptOptions.push(dept)
}
})
},
// 字典状态字典翻译
statusFormat(row) {
return this.selectDictLabel(this.statusOptions, parseInt(row.status))
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
deptId: undefined,
parentId: undefined,
deptName: undefined,
sort: 10,
leader: undefined,
phone: undefined,
email: undefined,
status: '2'
}
},
/** 搜索按钮操作 */
handleQuery() {
this.getList()
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset()
this.getTreeselect('add')
if (row !== undefined) {
this.form.parentId = row.deptId
}
this.open = true
this.title = '添加部门'
this.isEdit = false
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
this.getTreeselect('update')
getDept(row.deptId).then(response => {
this.form = response.data
this.form.status = String(this.form.status)
this.form.sort = String(this.form.sort)
this.open = true
this.title = '修改部门'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.form.status = parseInt(this.form.status)
this.form.sort = parseInt(this.form.sort)
if (this.form.deptId !== undefined) {
updateDept(this.form, this.form.deptId).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addDept(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const Ids = (row.deptId && [row.deptId]) || this.ids
this.$confirm(
'是否确认删除名称为"' + row.deptName + '"的数据项?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
.then(function() {
return delDept({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
}
}
}
</script>

View File

@ -0,0 +1,296 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="用户名" prop="username"><el-input
v-model="queryParams.username"
placeholder="请输入用户名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status"><el-select
v-model="queryParams.status"
placeholder="系统登录日志状态"
clearable
size="small"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="ip地址" prop="ipaddr"><el-input
v-model="queryParams.ipaddr"
placeholder="请输入ip地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysLoginLog:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="sysloginlogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="用户名"
align="center"
prop="username"
:show-overflow-tooltip="true"
/>
<el-table-column
label="类型"
align="center"
prop="msg"
:show-overflow-tooltip="true"
/>
<el-table-column
label="状态"
align="center"
prop="status"
:formatter="statusFormat"
width="100"
>
<template slot-scope="scope">
{{ statusFormat(scope.row) }}
</template>
</el-table-column>
<el-table-column
label="ip地址"
align="center"
prop="ipaddr"
>
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>IP: {{ scope.row.ipaddr }}</p>
<p>归属地: {{ scope.row.loginLocation }}</p>
<p>浏览器: {{ scope.row.browser }}</p>
<p>系统: {{ scope.row.os }}</p>
<p>固件: {{ scope.row.platform }}</p>
<div slot="reference" class="name-wrapper">
{{ scope.row.ipaddr }}
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="登录时间"
align="center"
prop="loginTime"
width="180"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.loginTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysLoginLog:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { delSysLoginlog, getSysLoginlog, listSysLoginlog } from '@/api/admin/sys-login-log'
export default {
name: 'SysLoginLogManage',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
fileOpen: false,
fileIndex: undefined,
// 类型数据字典
typeOptions: [],
sysloginlogList: [],
statusOptions: [],
// 关系表类型
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
username: undefined,
status: undefined,
ipaddr: undefined,
loginLocation: undefined,
createdAtOrder: 'desc'
},
// 表单参数
form: {
},
// 表单校验
rules: {
}
}
},
created() {
this.getList()
this.getDicts('sys_common_status').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listSysLoginlog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.sysloginlogList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
ID: undefined,
username: undefined,
status: undefined,
ipaddr: undefined,
loginLocation: undefined,
browser: undefined,
os: undefined,
platform: undefined,
loginTime: undefined,
remark: undefined,
msg: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
statusFormat(row) {
return this.selectDictLabel(this.statusOptions, row.status)
},
// 关系
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加系统登录日志'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const ID =
row.id || this.ids
getSysLoginlog(ID).then(response => {
this.form = response.data
this.open = true
this.title = '修改系统登录日志'
this.isEdit = true
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delSysLoginlog({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
}
}
}
</script>

View File

@ -0,0 +1,624 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form :inline="true">
<el-form-item label="菜单名称">
<el-input
v-model="queryParams.title"
placeholder="请输入菜单名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="queryParams.visible" placeholder="菜单状态" clearable size="small">
<el-option
v-for="dict in visibleOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button
v-permisaction="['admin:sysMenu:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="menuList"
border
row-key="menuId"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="title" label="菜单名称" :show-overflow-tooltip="true" width="180px" />
<el-table-column prop="icon" label="图标" align="center" width="100px">
<template slot-scope="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="60px" />
<el-table-column prop="permission" label="权限标识" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-popover v-if="scope.row.sysApi.length>0" trigger="hover" placement="top">
<el-table
:data="scope.row.sysApi"
border
style="width: 100%"
>
<el-table-column
prop="title"
label="title"
width="260px"
>
<template slot-scope="scope">
<span v-if="scope.row.type=='SYS' && scope.row.title!=''"><el-tag type="success">{{ '['+scope.row.type +'] '+ scope.row.title }}</el-tag></span>
<span v-if="scope.row.type!='SYS' && scope.row.title!=''"><el-tag type="">{{ '['+scope.row.type +'] '+scope.row.title }}</el-tag></span>
<span v-if="scope.row.title==''"><el-tag type="danger">暂无</el-tag></span>
</template>
</el-table-column>
<el-table-column
prop="path"
label="path"
width="270px"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.action=='GET'">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='POST'" type="success">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='PUT'" type="warning">{{ scope.row.action }}</el-tag>
<el-tag v-if="scope.row.action=='DELETE'" type="danger">{{ scope.row.action }}</el-tag>
{{ scope.row.path }}
</template>
</el-table-column>
</el-table>
<div slot="reference" class="name-wrapper">
<span v-if="scope.row.permission==''">-</span>
<span v-else>{{ scope.row.permission }}</span>
</div>
</el-popover>
<span v-else>
<span v-if="scope.row.permission==''">-</span>
<span v-else>{{ scope.row.permission }}</span>
</span>
</template>
</el-table-column>
<el-table-column prop="path" label="组件路径" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.menuType=='A'">{{ scope.row.path }}</span>
<span v-else>{{ scope.row.component }}</span>
</template>
</el-table-column>
<el-table-column prop="visible" label="可见" :formatter="visibleFormat" width="80">
<template slot-scope="scope">
<el-tag
:type="scope.row.visible === '1' ? 'danger' : 'success'"
disable-transitions
>{{ visibleFormat(scope.row) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdAt" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysMenu:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysMenu:add']"
size="mini"
type="text"
icon="el-icon-plus"
@click="handleAdd(scope.row)"
>新增</el-button>
<el-button
v-permisaction="['admin:sysMenu:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改菜单对话框 -->
<el-drawer
ref="drawer"
:title="title"
:before-close="cancel"
:visible.sync="open"
direction="rtl"
custom-class="demo-drawer"
size="830px"
>
<div class="demo-drawer__content">
<el-form ref="form" :model="form" :rules="rules" label-position="top" label-width="106px">
<el-row>
<el-col :span="24">
<el-form-item prop="parentId">
<span slot="label">
上级菜单
<el-tooltip content="指当前菜单停靠的菜单归属" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<treeselect
v-model="form.parentId"
:options="menuOptions"
:normalizer="normalizer"
:show-count="true"
placeholder="选择上级菜单"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="title">
<span slot="label">
菜单标题
<el-tooltip content="菜单位置显示的说明信息" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="form.title" placeholder="请输入菜单标题" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="sort">
<span slot="label">
显示排序
<el-tooltip content="根据序号升序排列" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input-number v-model="form.sort" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="menuType">
<span slot="label">
菜单类型
<el-tooltip content="包含目录:以及菜单或者菜单组,菜单:具体对应某一个页面,按钮:功能才做按钮;" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-radio-group v-model="form.menuType">
<el-radio label="M">目录</el-radio>
<el-radio label="C">菜单</el-radio>
<el-radio label="F">按钮</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="菜单图标">
<el-popover
placement="bottom-start"
width="460"
trigger="click"
@show="$refs['iconSelect'].reset()"
>
<IconSelect ref="iconSelect" @selected="selected" />
<el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
<svg-icon
v-if="form.icon"
slot="prefix"
:icon-class="form.icon"
class="el-input__icon"
style="height: 32px;width: 16px;"
/>
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
</el-input>
</el-popover>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType == 'M' || form.menuType == 'C'" prop="menuName">
<span slot="label">
路由名称
<el-tooltip content="需要和页面name保持一致对应页面即可选择缓存" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="form.menuName" placeholder="请输入路由名称" />
</el-form-item>
</el-col>
<el-col v-if="form.menuType == 'M' || form.menuType == 'C'" :span="12">
<el-form-item prop="component">
<span slot="label">
组件路径
<el-tooltip content="菜单对应的具体vue页面文件路径views的下级路径/admin/sys-api/index目录类型填写Layout如何有二级目录请参照日志目录填写" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="form.component" placeholder="请输入组件路径" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType == 'M' || form.menuType == 'C'">
<span slot="label">
是否外链
<el-tooltip content="可以通过iframe打开指定地址" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-radio-group v-model="form.isFrame">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType != 'F'" prop="path">
<span slot="label">
路由地址
<el-tooltip content="访问此页面自定义的url地址建议/开头书写,例如 /app-name/menu-name" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType == 'F' || form.menuType == 'C'">
<span slot="label">
权限标识
<el-tooltip content="前端权限控制按钮是否显示" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="form.permission" placeholder="请权限标识" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType != 'F'">
<span slot="label">
菜单状态
<el-tooltip content="需要显示在菜单列表的菜单设置为显示,否则设置为隐藏" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-radio-group v-model="form.visible">
<el-radio
v-for="dict in visibleOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item v-if="form.menuType == 'F' || form.menuType == 'C'">
<span slot="label">
api权限
<el-tooltip content="配置在这个才做上需要使用到的接口,否则在设置用户角色时,接口将无权访问。" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-transfer
v-model="form.apis"
style="text-align: left; display: inline-block"
filterable
:props="{
key: 'id',
label: 'title'
}"
:titles="['未授权', '已授权']"
:button-texts="['收回', '授权 ']"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}'
}"
class="panel"
:data="sysapiList"
@change="handleChange"
>
<span slot-scope="{ option }">{{ option.title }}</span>
</el-transfer>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="demo-drawer__footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</div>
</el-drawer>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listMenu, getMenu, delMenu, addMenu, updateMenu } from '@/api/admin/sys-menu'
import { listSysApi } from '@/api/admin/sys-api'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import IconSelect from '@/components/IconSelect'
export default {
name: 'SysMenuManage',
components: { Treeselect, IconSelect },
data() {
return {
// 遮罩层
loading: true,
// 菜单表格树数据
menuList: [],
sysapiList: [],
// 菜单树选项
menuOptions: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 菜单状态数据字典
visibleOptions: [],
// 查询参数
queryParams: {
title: undefined,
visible: undefined
},
// 表单参数
form: {
apis: [],
sysApi: []
},
// 表单校验
rules: {
title: [{ required: true, message: '菜单标题不能为空', trigger: 'blur' }],
sort: [{ required: true, message: '菜单顺序不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
this.getApiList()
this.getDicts('sys_show_hide').then(response => {
this.visibleOptions = response.data
})
},
methods: {
handleChange(value, direction, movedKeys) {
console.log(value, direction, movedKeys)
const list = this.form.sysApi
this.form.apis = value
if (direction === 'right') {
for (let x = 0; x < movedKeys.length; x++) {
for (let index = 0; index < this.sysapiList.length; index++) {
const element = this.sysapiList[index]
if (element.id === movedKeys[x]) {
list.push(element)
break
}
}
}
this.form.sysApi = list
} else if (direction === 'left') {
const l = []
for (let index = 0; index < movedKeys.length; index++) {
const element = movedKeys[index]
for (let x = 0; x < list.length; x++) {
const e = list[x]
if (element !== e.id) {
l.push()
break
}
}
}
this.form.sysApi = l
}
// this.setApis(this.form.SysApi)
console.log(this.form.sysApi)
},
getApiList() {
this.loading = true
listSysApi({ 'pageSize': 10000, 'type': 'BUS' }).then(response => {
this.sysapiList = response.data.list
this.loading = false
}
)
},
handleClose(done) {
// if (this.loading) {
// return
// }
// this.$confirm('需要提交表单吗?')
// .then(_ => {
// this.loading = true
// this.timer = setTimeout(() => {
// done()
// // 动画关闭需要一定的时间
// setTimeout(() => {
// this.loading = false
// }, 400)
// }, 1000)
// })
// .catch(_ => {})
},
// 选择图标
selected(name) {
this.form.icon = name
},
/** 查询菜单列表 */
getList() {
this.loading = true
listMenu(this.queryParams).then(response => {
this.menuList = response.data
this.loading = false
})
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.menuId,
label: node.title,
children: node.children
}
},
/** 查询菜单下拉树结构 */
getTreeselect() {
listMenu().then(response => {
this.menuOptions = []
const menu = { menuId: 0, title: '主类目', children: [] }
menu.children = response.data
this.menuOptions.push(menu)
})
},
// 菜单显示状态字典翻译
visibleFormat(row) {
if (row.menuType === 'F') {
return '-- --'
}
return this.selectDictLabel(this.visibleOptions, row.visible)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
menuId: undefined,
parentId: 0,
menuName: undefined,
icon: undefined,
menuType: 'M',
apis: [],
sort: 0,
action: this.form.menuType === 'A' ? this.form.action : '',
isFrame: '1',
visible: '0'
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.getList()
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset()
this.getTreeselect()
if (row != null) {
this.form.parentId = row.menuId
}
this.open = true
this.title = '添加菜单'
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
this.getTreeselect()
getMenu(row.menuId).then(response => {
this.form = response.data
this.open = true
this.title = '修改菜单'
})
},
setApis(apiArray) {
var l = []
for (var index = 0; index < apiArray.length; index++) {
const element = apiArray[index]
l.push(element.id)
}
this.form.apis = l
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.menuId !== undefined) {
updateMenu(this.form, this.form.menuId).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addMenu(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm('是否确认删除名称为"' + row.title + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
var Ids = (row.menuId && [row.menuId]) || this.ids
return delMenu({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
}
}
}
</script>
<style lang="css">
.panel .el-transfer__buttons{
width: 150px;
}
.panel .el-transfer__buttons .el-button + .el-button{
margin-left:0;
}
.panel .el-transfer-panel{
width: 300px;
}
.el-col {
padding: 0 5px;
}
.el-drawer__header{
margin-bottom: 0;
}
</style>

View File

@ -0,0 +1,334 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="操作状态"
clearable
size="small"
style="width: 160px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
size="small"
type="datetimerange"
:picker-options="pickerOptions"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right"
value-format="yyyy-MM-dd HH:mm:ss"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysOperLog:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysOperLog:export']"
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="list" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="编号" width="70" prop="id" />
<el-table-column
label="Request info"
prop="operUrl"
>
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>Request:
<el-tag v-if="scope.row.requestMethod=='GET'">{{ scope.row.requestMethod }}</el-tag>
<el-tag v-if="scope.row.requestMethod=='POST'" type="success">{{ scope.row.requestMethod }}</el-tag>
<el-tag v-if="scope.row.requestMethod=='PUT'" type="warning">{{ scope.row.requestMethod }}</el-tag>
<el-tag v-if="scope.row.requestMethod=='DELETE'" type="danger">{{ scope.row.requestMethod }}</el-tag>
{{ scope.row.operUrl }}
</p>
<p>Host: {{ scope.row.operIp }}</p>
<p>Location: {{ scope.row.operLocation }}</p>
<p>耗时: {{ scope.row.latencyTime }}</p>
<div slot="reference" class="name-wrapper">
<el-tag v-if="scope.row.requestMethod=='GET'">{{ scope.row.requestMethod }}</el-tag>
<el-tag v-if="scope.row.requestMethod=='POST'" type="success">{{ scope.row.requestMethod }}</el-tag>
<el-tag v-if="scope.row.requestMethod=='PUT'" type="warning">{{ scope.row.requestMethod }}</el-tag>
<el-tag v-if="scope.row.requestMethod=='DELETE'" type="danger">{{ scope.row.requestMethod }}</el-tag>
{{ scope.row.operUrl }}
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="操作人员"
prop="operName"
width="160"
:show-overflow-tooltip="true"
/>
<el-table-column
label="状态"
prop="status"
width="80"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.status=='2'" type="success">{{ statusFormat(scope.row,scope.row.status) }}</el-tag>
<el-tag v-if="scope.row.status=='1'" type="danger">{{ statusFormat(scope.row,scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作日期" prop="operTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.operTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="80"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysOperLog:query']"
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row,scope.index)"
>详细</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 操作日志详细 -->
<el-dialog title="操作日志详细" :visible.sync="open" width="700px" :close-on-click-modal="false">
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="24">
<el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="登录信息:"
>{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="耗时:">{{ form.latencyTime }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="请求参数:">{{ form.operParam }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="操作状态:">
<div v-if="form.status === '2'">正常</div>
<div v-else-if="form.status === '1'">关闭</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item v-if="form.status === 1" label="异常信息:">{{ form.errorMsg }}</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listSysOperlog, delSysOperlog, cleanOperlog } from '@/api/admin/sys-opera-log'
import { formatJson } from '@/utils'
export default {
name: 'SysOperLogManage',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 表格数据
list: [],
// 是否显示弹出层
open: false,
// 类型数据字典
statusOptions: [],
// 日期范围
dateRange: [],
// 表单参数
form: {},
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
title: undefined,
operName: undefined,
businessType: undefined,
status: undefined,
createdAtOrder: 'desc'
}
}
},
created() {
this.getList()
this.getDicts('sys_common_status').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询登录日志 */
getList() {
this.loading = true
listSysOperlog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.list = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 操作日志状态字典翻译
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status)
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.multiple = !selection.length
},
/** 详细按钮操作 */
handleView(row) {
this.open = true
this.form = row
},
/** 删除按钮操作 */
handleDelete(row) {
const operIds = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除日志编号为"' + operIds + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delSysOperlog({ 'ids': operIds })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 清空按钮操作 */
handleClean() {
this.$confirm('是否确认清空所有操作日志数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return cleanOperlog()
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
// const queryParams = this.queryParams
this.$confirm('是否确认导出所有操作日志数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['日志编号', '系统模块', '操作类型', '请求方式', '操作人员', '主机', '操作地点', '操作状态', '操作url', '操作日期']
const filterVal = ['ID', 'title', 'businessType', 'method', 'operName', 'operIp', 'operLocation', 'status', 'operUrl', 'operTime']
const list = this.list
const data = formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: '操作日志',
autoWidth: true, // Optional
bookType: 'xlsx' // Optional
})
this.downloadLoading = false
})
})
}
}
}
</script>

View File

@ -0,0 +1,360 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="岗位编码" prop="postCode">
<el-input
v-model="queryParams.postCode"
placeholder="请输入岗位编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="岗位名称" prop="postName">
<el-input
v-model="queryParams.postName"
placeholder="请输入岗位名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysPost:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysPost:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysPost:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysPost:export']"
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="postList" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="岗位编号" width="80" align="center" prop="postId" />
<el-table-column label="岗位编码" align="center" prop="postCode" />
<el-table-column label="岗位名称" align="center" prop="postName" />
<el-table-column label="岗位排序" align="center" prop="sort" />
<el-table-column label="状态" align="center" prop="status" :formatter="statusFormat">
<template slot-scope="scope">
<el-tag
:type="scope.row.status === 1 ? 'danger' : 'success'"
disable-transitions
>{{ statusFormat(scope.row) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdAt" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysPost:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysPost:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改岗位对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="岗位名称" prop="postName">
<el-input v-model="form.postName" placeholder="请输入岗位名称" />
</el-form-item>
<el-form-item label="岗位编码" prop="postCode">
<el-input v-model="form.postCode" placeholder="请输入编码名称" />
</el-form-item>
<el-form-item label="岗位顺序" prop="sort">
<el-input-number v-model="form.sort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="岗位状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listPost, getPost, delPost, addPost, updatePost } from '@/api/admin/sys-post'
import { formatJson } from '@/utils'
export default {
name: 'SysPostManage',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 岗位表格数据
postList: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 状态数据字典
statusOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
postCode: undefined,
postName: undefined,
status: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {
postName: [
{ required: true, message: '岗位名称不能为空', trigger: 'blur' }
],
postCode: [
{ required: true, message: '岗位编码不能为空', trigger: 'blur' }
],
sort: [
{ required: true, message: '岗位顺序不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getList()
this.getDicts('sys_normal_disable').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询岗位列表 */
getList() {
this.loading = true
listPost(this.queryParams).then(response => {
this.postList = response.data.list
this.total = response.data.count
this.loading = false
})
},
// 岗位状态字典翻译
statusFormat(row) {
return this.selectDictLabel(this.statusOptions, row.status)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
postId: undefined,
postCode: undefined,
postName: undefined,
sort: 0,
status: '1',
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.postId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加岗位'
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const postId = row.postId || this.ids
getPost(postId).then(response => {
this.form = response.data
this.form.status = String(this.form.status)
this.open = true
this.title = '修改岗位'
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.form.status = parseInt(this.form.status)
if (this.form.postId !== undefined) {
updatePost(this.form, this.form.postId).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addPost(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
// const postIds = row.postId || this.ids
const Ids = (row.postId && [row.postId]) || this.ids
this.$confirm('是否确认删除岗位编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delPost({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
// const queryParams = this.queryParams
this.$confirm('是否确认导出所有岗位数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['岗位编号', '岗位编码', '岗位名称', '排序', '创建时间']
const filterVal = ['postId', 'postCode', 'postName', 'sort', 'createdAt']
const list = this.postList
const data = formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: '岗位管理',
autoWidth: true, // Optional
bookType: 'xlsx' // Optional
})
this.downloadLoading = false
})
}).catch(function() {})
}
}
}
</script>

View File

@ -0,0 +1,611 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item label="名称" prop="roleName">
<el-input
v-model="queryParams.roleName"
placeholder="请输入角色名称"
clearable
size="small"
style="width: 160px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="权限字符" prop="roleKey">
<el-input
v-model="queryParams.roleKey"
placeholder="请输入权限字符"
clearable
size="small"
style="width: 160px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="角色状态"
clearable
size="small"
style="width: 160px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysRole:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysRole:update']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysRole:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysRole:export']"
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="roleList"
border
@selection-change="handleSelectionChange"
@sort-change="handleSortChang"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="编码" sortable="custom" prop="roleId" width="80" />
<el-table-column label="名称" sortable="custom" prop="roleName" :show-overflow-tooltip="true" />
<el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
<el-table-column label="排序" sortable="custom" prop="roleSort" width="80" />
<el-table-column label="状态" sortable="custom" width="80">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="2"
inactive-value="1"
@change="handleStatusChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="创建时间" sortable="custom" prop="createdAt" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="left"
class-name="small-padding fixed-width"
width="220"
>
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysRole:update']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-permisaction="['admin:sysRole:update']"
size="mini"
type="text"
icon="el-icon-circle-check"
@click="handleDataScope(scope.row)"
>数据权限</el-button>
<el-button
v-if="scope.row.roleKey!=='admin'"
v-permisaction="['admin:sysRole:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改角色配置对话框 -->
<el-dialog v-if="open" :title="title" :visible.sync="open" width="500px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="角色名称" prop="roleName">
<el-input v-model="form.roleName" placeholder="请输入角色名称" :disabled="isEdit" />
</el-form-item>
<el-form-item label="权限字符" prop="roleKey">
<el-input v-model="form.roleKey" placeholder="请输入权限字符" :disabled="isEdit" />
</el-form-item>
<el-form-item label="角色顺序" prop="roleSort">
<el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="菜单权限">
<el-tree
ref="menuTree"
:data="menuOptions"
show-checkbox
node-key="id"
:empty-text="menuOptionsAlert"
style="height:171px;overflow-y:auto;overflow-x:hidden;"
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 分配角色数据权限对话框 -->
<el-dialog v-if="openDataScope" :title="title" :visible.sync="openDataScope" width="500px" :close-on-click-modal="false">
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.roleName" :disabled="true" />
</el-form-item>
<el-form-item label="权限字符">
<el-input v-model="form.roleKey" :disabled="true" />
</el-form-item>
<el-form-item label="权限范围">
<el-select v-model="form.dataScope">
<el-option
v-for="item in dataScopeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-show="form.dataScope == 2" label="数据权限">
<el-tree
ref="dept"
:data="deptOptions"
show-checkbox
default-expand-all
node-key="id"
empty-text="加载中请稍后"
:props="defaultProps"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitDataScope"> </el-button>
<el-button @click="cancelDataScope"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from '@/api/admin/sys-role'
import { roleMenuTreeselect } from '@/api/admin/sys-menu'
import { treeselect as deptTreeselect, roleDeptTreeselect } from '@/api/admin/sys-dept'
import { formatJson } from '@/utils'
export default {
name: 'Role',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 角色表格数据
roleList: [],
menuIdsChecked: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 是否显示弹出层(数据权限)
openDataScope: false,
isEdit: false,
// 日期范围
dateRange: [],
// 状态数据字典
statusOptions: [],
// 数据范围选项
dataScopeOptions: [
{
value: '1',
label: '全部数据权限'
},
{
value: '2',
label: '自定数据权限'
},
{
value: '3',
label: '本部门数据权限'
},
{
value: '4',
label: '本部门及以下数据权限'
},
{
value: '5',
label: '仅本人数据权限'
}
],
// 菜单列表
menuOptions: [],
menuList: [],
// 部门列表
deptOptions: [],
menuOptionsAlert: '加载中,请稍后',
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
roleName: undefined,
roleKey: undefined,
status: undefined
},
// 表单参数
form: {
sysMenu: []
},
defaultProps: {
children: 'children',
label: 'label'
},
// 表单校验
rules: {
roleName: [
{ required: true, message: '角色名称不能为空', trigger: 'blur' }
],
roleKey: [
{ required: true, message: '权限字符不能为空', trigger: 'blur' }
],
roleSort: [
{ required: true, message: '角色顺序不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getList()
this.getMenuTreeselect()
this.getDicts('sys_normal_disable').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询角色列表 */
getList() {
this.loading = true
listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
response => {
this.roleList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
/** 查询菜单树结构 */
getMenuTreeselect() {
roleMenuTreeselect(0).then(response => {
this.menuOptions = response.data.menus
this.menuList = this.menuOptions
})
},
/** 查询部门树结构 */
getDeptTreeselect() {
deptTreeselect().then(response => {
this.deptOptions = response.data.list
})
},
// 所有菜单节点数据
getMenuAllCheckedKeys() {
// 目前被选中的菜单节点
const checkedKeys = this.$refs.menuTree.getHalfCheckedKeys()
console.log('目前被选中的菜单节点', checkedKeys)
// 半选中的菜单节点
const halfCheckedKeys = this.$refs.menuTree.getCheckedKeys()
console.log('半选中的菜单节点', halfCheckedKeys)
// checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
return halfCheckedKeys
},
// 所有部门节点数据
getDeptAllCheckedKeys() {
// 目前被选中的部门节点
const checkedKeys = this.$refs.dept.getCheckedKeys()
// 半选中的部门节点
// const halfCheckedKeys = this.$refs.dept.getCheckedKeys()
// checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
return checkedKeys
},
/** 根据角色ID查询菜单树结构 */
getRoleMenuTreeselect(row, checkedKeys) {
if (row.roleKey === 'admin') {
this.menuOptionsAlert = '系统超级管理员无需此操作'
this.menuOptions = []
} else {
this.$nextTick(() => {
this.$refs.menuTree.setCheckedKeys(checkedKeys)
})
}
},
/** 根据角色ID查询部门树结构 */
getRoleDeptTreeselect(roleId) {
roleDeptTreeselect(roleId).then(response => {
this.deptOptions = response.data.depts
this.$nextTick(() => {
this.$refs.dept.setCheckedKeys(response.data.checkedKeys)
})
})
},
// 角色状态修改
handleStatusChange(row) {
const text = row.status === '2' ? '启用' : '停用'
this.$confirm('确认要"' + text + '""' + row.roleName + '"角色吗?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return changeRoleStatus(row.roleId, row.status)
}).then((res) => {
console.log('res', res)
this.msgSuccess(res.msg)
}).catch(function() {
row.status = row.status === '2' ? '1' : '2'
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 取消按钮(数据权限)
cancelDataScope() {
this.openDataScope = false
this.reset()
},
// 表单重置
reset() {
this.menuOptions = this.menuList
if (this.$refs.menuTree !== undefined) {
this.$refs.menuTree.setCheckedKeys([])
}
this.form = {
roleId: undefined,
roleName: undefined,
roleKey: undefined,
roleSort: 0,
status: '2',
menuIds: [],
deptIds: [],
sysMenu: [],
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.roleId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
// this.getMenuTreeselect(0)
this.open = true
this.title = '添加角色'
this.isEdit = false
},
handleSortChang(column, prop, order) {
prop = column.prop
order = column.order
if (order === 'descending') {
this.queryParams[prop + 'Order'] = 'desc'
} else if (order === 'ascending') {
this.queryParams[prop + 'Order'] = 'asc'
} else {
this.queryParams[prop + 'Order'] = undefined
}
this.getList()
},
/** 修改按钮操作 */
handleUpdate(row) {
this.menuIdsChecked = []
this.reset()
const roleId = row.roleId || this.ids
getRole(roleId).then(response => {
this.form = response.data
this.menuIdsChecked = response.data.menuIds
this.title = '修改角色'
this.isEdit = true
this.open = true
this.getRoleMenuTreeselect(row, response.data.menuIds)
})
},
/** 分配数据权限操作 */
handleDataScope(row) {
this.reset()
getRole(row.roleId).then(response => {
this.form = response.data
this.openDataScope = true
this.title = '分配数据权限'
this.getRoleDeptTreeselect(row.roleId)
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.roleId !== undefined) {
this.form.menuIds = this.getMenuAllCheckedKeys()
updateRole(this.form, this.form.roleId).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
this.form.menuIds = this.getMenuAllCheckedKeys()
addRole(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 提交按钮(数据权限) */
submitDataScope: function() {
if (this.form.roleId !== undefined) {
this.form.deptIds = this.getDeptAllCheckedKeys()
console.log(this.getDeptAllCheckedKeys())
dataScope(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.openDataScope = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
},
/** 删除按钮操作 */
handleDelete(row) {
const roleIds = (row.roleId && [row.roleId]) || this.ids
this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delRole({ 'ids': roleIds })
}).then((response) => {
this.getList()
this.msgSuccess(response.msg)
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
this.$confirm('是否确认导出所有角色数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['角色编号', '角色名称', '权限字符', '显示顺序', '状态', '创建时间']
const filterVal = ['roleId', 'roleName', 'roleKey', 'roleSort', 'status', 'createdAt']
const list = this.roleList
const data = formatJson(filterVal, list)
excel.export_json_to_excel({
header: tHeader,
data,
filename: '角色管理',
autoWidth: true, // Optional
bookType: 'xlsx' // Optional
})
this.downloadLoading = false
})
})
}
}
}
</script>

View File

@ -0,0 +1,681 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-row :gutter="20">
<!--部门数据-->
<el-col :span="4" :xs="24">
<div class="head-container">
<el-input
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
</div>
<div class="head-container">
<el-tree
ref="tree"
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
default-expand-all
@node-click="handleNodeClick"
/>
</div>
</el-col>
<!--用户数据-->
<el-col :span="20" :xs="24">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="用户名称" prop="username">
<el-input
v-model="queryParams.username"
placeholder="请输入用户名称"
clearable
size="small"
style="width: 160px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号码" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入手机号码"
clearable
size="small"
style="width: 160px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="用户状态"
clearable
size="small"
style="width: 160px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysUser:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysUser:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:sysUser:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="userList"
border
@selection-change="handleSelectionChange"
@sort-change="handleSortChang"
>
<el-table-column type="selection" width="45" align="center" />
<el-table-column label="编号" width="75" prop="userId" sortable="custom" />
<el-table-column label="登录名" width="105" prop="username" sortable="custom" :show-overflow-tooltip="true" />
<el-table-column label="昵称" prop="nickName" :show-overflow-tooltip="true" />
<el-table-column label="部门" prop="dept.deptName" :show-overflow-tooltip="true" />
<el-table-column label="手机号" prop="phone" width="108" />
<el-table-column label="状态" width="80" sortable="custom">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="2"
inactive-value="1"
@change="handleStatusChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="createdAt"
sortable="custom"
width="155"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="160"
fix="right"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
v-permisaction="['admin:sysUser:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-if="scope.row.userId !== 1"
v-permisaction="['admin:sysUser:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<el-button
v-permisaction="['admin:sysUser:resetPassword']"
size="mini"
type="text"
icon="el-icon-key"
@click="handleResetPwd(scope.row)"
>重置</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
</el-card>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户昵称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="归属部门" prop="deptId">
<treeselect
v-model="form.deptId"
:options="deptOptions"
placeholder="请选择归属部门"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号码" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号码" maxlength="11" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户名称" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择">
<el-option
v-for="dict in sexOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="岗位">
<el-select v-model="form.postId" placeholder="请选择" @change="$forceUpdate()">
<el-option
v-for="item in postOptions"
:key="item.postId"
:label="item.postName"
:value="item.postId"
:disabled="item.status == 1"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="角色">
<el-select v-model="form.roleId" placeholder="请选择" @change="$forceUpdate()">
<el-option
v-for="item in roleOptions"
:key="item.roleId"
:label="item.roleName"
:value="item.roleId"
:disabled="item.status == 1"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" :close-on-click-modal="false">
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<div slot="tip" class="el-upload__tip">
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
<el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
</div>
<div slot="tip" class="el-upload__tip" style="color:red">提示仅允许导入xlsxlsx格式文件</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</template>
</BasicLayout>
</template>
<script>
import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus, importTemplate } from '@/api/admin/sys-user'
import { getToken } from '@/utils/auth'
import { listPost } from '@/api/admin/sys-post'
import { listRole } from '@/api/admin/sys-role'
import { treeselect } from '@/api/admin/sys-dept'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
name: 'SysUserManage',
components: { Treeselect },
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 用户表格数据
userList: null,
// 弹出层标题
title: '',
// 部门树选项
deptOptions: undefined,
// 是否显示弹出层
open: false,
// 部门名称
deptName: undefined,
// 默认密码
initPassword: undefined,
// 日期范围
dateRange: [],
// 状态数据字典
statusOptions: [],
// 性别状态字典
sexOptions: [],
// 岗位选项
postOptions: [],
// 角色选项
roleOptions: [],
// 表单参数
form: {},
defaultProps: {
children: 'children',
label: 'label'
},
// 用户导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: 'Bearer ' + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + '/system/user/importData'
},
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
username: undefined,
phone: undefined,
status: undefined,
deptId: undefined
},
// 表单校验
rules: {
username: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }],
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
deptId: [{ required: true, message: '归属部门不能为空', trigger: 'blur' }],
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
email: [
{ required: true, message: '邮箱地址不能为空', trigger: 'blur' },
{ type: 'email', message: "'请输入正确的邮箱地址", trigger: ['blur', 'change'] }
],
phone: [
{ required: true, message: '手机号码不能为空', trigger: 'blur' },
{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }
]
}
}
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val)
}
},
created() {
this.getList()
this.getTreeselect()
this.getDicts('sys_normal_disable').then(response => {
this.statusOptions = response.data
})
this.getDicts('sys_user_sex').then(response => {
this.sexOptions = response.data
})
this.getConfigKey('sys_user_initPassword').then(response => {
this.initPassword = response.data.configValue
})
},
methods: {
/** 查询用户列表 */
getList() {
this.loading = true
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.userList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
/** 查询部门下拉树结构 */
getTreeselect() {
treeselect().then(response => {
this.deptOptions = response.data
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
this.queryParams.deptId = '/' + data.id + '/'
this.getList()
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.id,
label: node.label,
children: node.children
}
},
/** 排序回调函数 */
handleSortChang(column, prop, order) {
prop = column.prop
order = column.order
if (this.order !== '' && this.order !== prop + 'Order') {
this.queryParams[this.order] = undefined
}
if (order === 'descending') {
this.queryParams[prop + 'Order'] = 'desc'
this.order = prop + 'Order'
} else if (order === 'ascending') {
this.queryParams[prop + 'Order'] = 'asc'
this.order = prop + 'Order'
} else {
this.queryParams[prop + 'Order'] = undefined
}
this.getList()
},
// 用户状态修改
handleStatusChange(row) {
const text = row.status === '2' ? '启用' : '停用'
this.$confirm('确认要"' + text + '""' + row.username + '"用户吗?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return changeUserStatus(row)
}).then(() => {
this.msgSuccess(text + '成功')
}).catch(function() {
row.status = row.status === '2' ? '1' : '2'
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
userId: undefined,
deptId: undefined,
username: undefined,
nickName: undefined,
password: undefined,
phone: undefined,
email: undefined,
sex: undefined,
status: '2',
remark: undefined,
postIds: undefined,
roleIds: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.page = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.queryParams.deptId = ''
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.userId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.getTreeselect()
listPost({ pageSize: 1000 }).then(response => {
this.postOptions = response.data.list
})
listRole({ pageSize: 1000 }).then(response => {
this.roleOptions = response.data.list
})
this.open = true
this.title = '添加用户'
this.form.password = this.initPassword
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const userId = row.userId || this.ids
getUser(userId).then(response => {
this.form = response.data
this.open = true
this.title = '修改用户'
this.form.password = ''
})
listPost({ pageSize: 1000 }).then(response => {
this.postOptions = response.data.list
})
listRole({ pageSize: 1000 }).then(response => {
this.roleOptions = response.data.list
})
},
/** 重置密码按钮操作 */
handleResetPwd(row) {
this.$prompt('请输入"' + row.username + '"的新密码', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
} else {
this.msgError(response.msg)
}
})
}).catch(() => {})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.userId !== undefined) {
updateUser(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addUser(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const Ids = (row.userId && [row.userId]) || this.ids
this.$confirm('是否确认删除用户编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delUser({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams
this.$confirm('是否确认导出所有用户数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return exportUser(queryParams)
}).then(response => {
this.download(response.msg)
}).catch(function() {})
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = '用户导入'
this.upload.open = true
},
/** 下载模板操作 */
importTemplate() {
importTemplate().then(response => {
this.download(response.msg)
})
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles()
this.$alert(response.msg, '导入结果', { dangerouslyUseHTMLString: true })
this.getList()
},
// 提交上传文件
submitFileForm() {
this.$refs.upload.submit()
}
}
}
</script>

View File

@ -0,0 +1,523 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="币种" prop="coinCode"><el-input
v-model="queryParams.coinCode"
placeholder="请输入币种"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订单号" prop="orderNo"><el-input
v-model="queryParams.orderNo"
placeholder="请输入订单号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="用户id" prop="adUserId"><el-select v-model="queryParams.adUserId"
placeholder="请选择" clearable size="small" >
<el-option
v-for="dict in adUserIdOptions"
:key="dict.key"
:label="dict.value"
:value="dict.key"
/>
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['admin:vtsRecharge:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:vtsRecharge:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['admin:vtsRecharge:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="vtsRechargeList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /><el-table-column
label="币种"
align="center"
prop="coinCode"
:show-overflow-tooltip="true"
/><el-table-column
label="类型"
align="center"
prop="tranType"
:show-overflow-tooltip="true"
>
<template #default="{row}">
{{ ['线上', '内部'][row.tranType-1] }}
</template>
</el-table-column>
<el-table-column
label="订单号"
align="center"
prop="orderNo"
:show-overflow-tooltip="true"
/><el-table-column label="用户id" align="center" prop="adUserId" :formatter="adUserIdFormat" width="100">
<template slot-scope="scope">
{{ adUserIdFormat(scope.row) }}
</template>
</el-table-column><el-table-column
label="订单价格"
align="center"
prop="amount"
:show-overflow-tooltip="true"
/><el-table-column
label="CoinGate结算货币代码"
align="center"
prop="priceCurrency"
:show-overflow-tooltip="true"
/><el-table-column
label="实收数量"
align="center"
prop="receiveAmount"
:show-overflow-tooltip="true"
/><el-table-column
label="实际支付数量"
align="center"
prop="payAmount"
:show-overflow-tooltip="true"
/><el-table-column
label="实际支付的加密货币"
align="center"
prop="payCurrency"
:show-overflow-tooltip="true"
/><el-table-column
label="手续费"
align="center"
prop="fee"
:show-overflow-tooltip="true"
/><el-table-column
label="状态"
align="center"
prop="status"
:show-overflow-tooltip="true"
/><el-table-column
label="确认状态"
align="center"
prop="confirmStatus"
:show-overflow-tooltip="true"
/><el-table-column
label="备注"
align="center"
prop="remark"
:show-overflow-tooltip="true"
/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popconfirm
class="delete-popconfirm"
title="确认要修改吗?"
confirm-button-text="修改"
@confirm="handleUpdate(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:vtsRecharge:edit']"
size="mini"
type="text"
icon="el-icon-edit"
>修改
</el-button>
</el-popconfirm>
<el-popconfirm
class="delete-popconfirm"
title="确认要删除吗?"
confirm-button-text="删除"
@confirm="handleDelete(scope.row)"
>
<el-button
slot="reference"
v-permisaction="['admin:vtsRecharge:remove']"
size="mini"
type="text"
icon="el-icon-delete"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="币种" prop="coinCode">
<el-input
v-model="form.coinCode"
placeholder="币种"
/>
</el-form-item>
<el-form-item label="类型" prop="tranType">
<el-radio-group v-model="form.tranType">
<el-radio :label="1">线上</el-radio>
<el-radio :label="2">内部</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="订单号" prop="orderNo">
<el-input
v-model="form.orderNo"
placeholder="订单号"
/>
</el-form-item>
<el-form-item label="用户id" prop="adUserId">
<el-input
v-model="form.adUserId"
placeholder="用户id"
/>
</el-form-item>
<el-form-item label="订单价格" prop="amount">
<el-input
v-model="form.amount"
placeholder="订单价格"
/>
</el-form-item>
<el-form-item label="CoinGate结算货币代码" prop="priceCurrency">
<el-input
v-model="form.priceCurrency"
placeholder="CoinGate结算货币代码"
/>
</el-form-item>
<el-form-item label="实收数量" prop="receiveAmount">
<el-input
v-model="form.receiveAmount"
placeholder="实收数量"
/>
</el-form-item>
<el-form-item label="实际支付数量" prop="payAmount">
<el-input
v-model="form.payAmount"
placeholder="实际支付数量"
/>
</el-form-item>
<el-form-item label="实际支付的加密货币" prop="payCurrency">
<el-input
v-model="form.payCurrency"
placeholder="实际支付的加密货币"
/>
</el-form-item>
<el-form-item label="买家少付数量" prop="underpaidAmount">
<el-input
v-model="form.underpaidAmount"
placeholder="买家少付数量"
/>
</el-form-item>
<el-form-item label="买家多付数量" prop="overpaidAmount">
<el-input
v-model="form.overpaidAmount"
placeholder="买家多付数量"
/>
</el-form-item>
<el-form-item label="指示购物者是否可以请求发票退款" prop="isRefundable">
<el-input
v-model="form.isRefundable"
placeholder="指示购物者是否可以请求发票退款"
/>
</el-form-item>
<el-form-item label="第三方创建时间" prop="walletCreateAt">
<el-date-picker
v-model="form.walletCreateAt"
type="datetime"
placeholder="选择日期"
/>
</el-form-item>
<el-form-item label="第三方钱包订单" prop="walletId">
<el-input
v-model="form.walletId"
placeholder="第三方钱包订单"
/>
</el-form-item>
<el-form-item label="手续费" prop="fee">
<el-input
v-model="form.fee"
placeholder="手续费"
/>
</el-form-item>
<el-form-item label="回调时间" prop="callbackAt">
<el-date-picker
v-model="form.callbackAt"
type="datetime"
placeholder="选择日期"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-input
v-model="form.status"
placeholder="状态"
/>
</el-form-item>
<el-form-item label="确认状态" prop="confirmStatus">
<el-input
v-model="form.confirmStatus"
placeholder="确认状态"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
placeholder="备注"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { addVtsRecharge, delVtsRecharge, getVtsRecharge, listVtsRecharge, updateVtsRecharge } from '@/api/admin/vts-recharge'
import { listLineUser } from '@/api/admin/line-user'
export default {
name: 'VtsRecharge',
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
vtsRechargeList: [],
// 关系表类型
adUserIdOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
coinCode: undefined,
orderNo: undefined,
adUserId: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: { coinCode: [{ required: true, message: '币种不能为空', trigger: 'blur' }],
orderNo: [{ required: true, message: '订单号不能为空', trigger: 'blur' }],
adUserId: [{ required: true, message: '用户id不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
this.getLineUserItems()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listVtsRecharge(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.vtsRechargeList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
coinCode: undefined,
tranType: 1,
orderNo: undefined,
adUserId: undefined,
amount: undefined,
priceCurrency: undefined,
receiveAmount: undefined,
payAmount: undefined,
payCurrency: undefined,
underpaidAmount: undefined,
overpaidAmount: undefined,
isRefundable: undefined,
walletCreateAt: undefined,
walletId: undefined,
fee: undefined,
callbackAt: undefined,
status: undefined,
confirmStatus: undefined,
remark: undefined
}
this.resetForm('form')
},
getImgList: function() {
this.form[this.fileIndex] = this.$refs['fileChoose'].resultList[0].fullUrl
},
fileClose: function() {
this.fileOpen = false
},
adUserIdFormat(row) {
return this.selectItemsLabel(this.adUserIdOptions, row.adUserId)
},
// 关系
getLineUserItems() {
this.getItems(listLineUser, undefined).then(res => {
this.adUserIdOptions = this.setItems(res, 'id', 'username')
})
},
// 文件
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加coinGate充值记录表'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id =
row.id || this.ids
getVtsRecharge(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改coinGate充值记录表'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
updateVtsRecharge(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addVtsRecharge(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
var Ids = (row.id && [row.id]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delVtsRecharge({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {
})
}
}
}
</script>

View File

@ -0,0 +1,102 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 6000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
top: 10,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisTick: {
show: false
}
}],
series: [{
name: 'pageA',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
animationDuration
}]
})
}
}
}
</script>

View File

@ -0,0 +1,135 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
setOptions({ expectedData, actualData } = {}) {
this.chart.setOption({
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['expected', 'actual']
},
series: [{
name: 'expected', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: expectedData,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: 'actual',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: actualData,
animationDuration: 2800,
animationEasing: 'quadraticOut'
}]
})
}
}
}
</script>

View File

@ -0,0 +1,181 @@
<template>
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
新用户
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="message" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
消息
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
金额
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
销量
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
export default {
components: {
CountTo
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-people {
background: #40c9c6;
}
.icon-message {
background: #36a3f7;
}
.icon-money {
background: #f4516c;
}
.icon-shopping {
background: #34bfa3
}
}
.icon-people {
color: #40c9c6;
}
.icon-message {
color: #36a3f7;
}
.icon-money {
color: #f4516c;
}
.icon-shopping {
color: #34bfa3
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width:550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>

View File

@ -0,0 +1,79 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
</script>

View File

@ -0,0 +1,116 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 3000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Techology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
}
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: 'Allocated Budget'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: 'Expected Spending'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: 'Actual Spending'
}
],
animationDuration: animationDuration
}]
})
}
}
}
</script>

View File

@ -0,0 +1,81 @@
<template>
<li :class="{ completed: todo.done, editing: editing }" class="todo">
<div class="view">
<input
:checked="todo.done"
class="toggle"
type="checkbox"
@change="toggleTodo( todo)"
>
<label @dblclick="editing = true" v-text="todo.text" />
<button class="destroy" @click="deleteTodo( todo )" />
</div>
<input
v-show="editing"
v-focus="editing"
:value="todo.text"
class="edit"
@keyup.enter="doneEdit"
@keyup.esc="cancelEdit"
@blur="doneEdit"
>
</li>
</template>
<script>
export default {
name: 'Todo',
directives: {
focus(el, { value }, { context }) {
if (value) {
context.$nextTick(() => {
el.focus()
})
}
}
},
props: {
todo: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
editing: false
}
},
methods: {
deleteTodo(todo) {
this.$emit('deleteTodo', todo)
},
editTodo({ todo, value }) {
this.$emit('editTodo', { todo, value })
},
toggleTodo(todo) {
this.$emit('toggleTodo', todo)
},
doneEdit(e) {
const value = e.target.value.trim()
const { todo } = this
if (!value) {
this.deleteTodo({
todo
})
} else if (this.editing) {
this.editTodo({
todo,
value
})
this.editing = false
}
},
cancelEdit(e) {
e.target.value = this.todo.text
this.editing = false
}
}
}
</script>

View File

@ -0,0 +1,320 @@
.todoapp {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
color: #4d4d4d;
min-width: 230px;
max-width: 550px;
margin: 0 auto ;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-weight: 300;
background: #fff;
z-index: 1;
position: relative;
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
:focus {
outline: 0;
}
.hidden {
display: none;
}
.todoapp {
background: #fff;
margin: 130px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.todoapp input::-webkit-input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::-moz-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp h1 {
position: absolute;
top: -155px;
width: 100%;
font-size: 100px;
font-weight: 100;
text-align: center;
color: rgba(175, 47, 47, 0.15);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
.new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 18px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.new-todo {
padding: 10px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
}
.main {
position: relative;
z-index: 2;
border-top: 1px solid #e6e6e6;
}
.toggle-all {
text-align: center;
border: none;
/* Mobile Safari */
opacity: 0;
position: absolute;
}
.toggle-all+label {
width: 60px;
height: 34px;
font-size: 0;
position: absolute;
top: -52px;
left: -13px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.toggle-all+label:before {
content: '';
font-size: 22px;
color: #e6e6e6;
padding: 10px 27px 10px 27px;
}
.toggle-all:checked+label:before {
color: #737373;
}
.todo-list {
margin: 0;
padding: 0;
list-style: none;
}
.todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px solid #ededed;
}
.todo-list li:last-child {
border-bottom: none;
}
.todo-list li.editing {
border-bottom: none;
padding: 0;
}
.todo-list li.editing .edit {
display: block;
width: 506px;
padding: 12px 16px;
margin: 0 0 0 43px;
}
.todo-list li.editing .view {
display: none;
}
.todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none;
/* Mobile Safari */
-webkit-appearance: none;
appearance: none;
}
.todo-list li .toggle {
opacity: 0;
}
.todo-list li .toggle+label {
/*
Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
*/
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
background-repeat: no-repeat;
background-position: center left;
background-size: 36px;
}
.todo-list li .toggle:checked+label {
background-size: 36px;
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
}
.todo-list li label {
word-break: break-all;
padding: 15px 15px 15px 50px;
display: block;
line-height: 1.0;
font-size: 14px;
transition: color 0.4s;
}
.todo-list li.completed label {
color: #d9d9d9;
text-decoration: line-through;
}
.todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 30px;
color: #cc9a9a;
transition: color 0.2s ease-out;
cursor: pointer;
}
.todo-list li .destroy:hover {
color: #af5b5e;
}
.todo-list li .destroy:after {
content: '×';
}
.todo-list li:hover .destroy {
display: block;
}
.todo-list li .edit {
display: none;
}
.todo-list li.editing:last-child {
margin-bottom: -1px;
}
.footer {
color: #777;
position: relative;
padding: 10px 15px;
height: 40px;
text-align: center;
border-top: 1px solid #e6e6e6;
}
.footer:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 40px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.todo-count strong {
font-weight: 300;
}
.filters {
margin: 0;
padding: 0;
position: relative;
z-index: 1;
list-style: none;
}
.filters li {
display: inline;
}
.filters li a {
color: inherit;
font-size: 12px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
.filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
}
.filters li a.selected {
border-color: rgba(175, 47, 47, 0.2);
}
.clear-completed,
html .clear-completed:active {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
cursor: pointer;
}
.clear-completed:hover {
text-decoration: underline;
}
.info {
margin: 65px auto 0;
color: #bfbfbf;
font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center;
}
.info p {
line-height: 1;
}
.info a {
color: inherit;
text-decoration: none;
font-weight: 400;
}
.info a:hover {
text-decoration: underline;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
.toggle-all,
.todo-list li .toggle {
background: none;
}
.todo-list li .toggle {
height: 40px;
}
}
@media (max-width: 430px) {
.footer {
height: 50px;
}
.filters {
bottom: 10px;
}
}
}

View File

@ -0,0 +1,127 @@
<template>
<section class="todoapp">
<!-- header -->
<header class="header">
<input class="new-todo" autocomplete="off" placeholder="Todo List" @keyup.enter="addTodo">
</header>
<!-- main section -->
<section v-show="todos.length" class="main">
<input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })">
<label for="toggle-all" />
<ul class="todo-list">
<todo
v-for="(todo, index) in filteredTodos"
:key="index"
:todo="todo"
@toggleTodo="toggleTodo"
@editTodo="editTodo"
@deleteTodo="deleteTodo"
/>
</ul>
</section>
<!-- footer -->
<footer v-show="todos.length" class="footer">
<span class="todo-count">
<strong>{{ remaining }}</strong>
{{ remaining | pluralize('item') }} left
</span>
<ul class="filters">
<li v-for="(val, key) in filters" :key="key">
<a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>
</li>
</ul>
<!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted">
Clear completed
</button> -->
</footer>
</section>
</template>
<script>
import Todo from './Todo.vue'
const STORAGE_KEY = 'todos'
const filters = {
all: todos => todos,
active: todos => todos.filter(todo => !todo.done),
completed: todos => todos.filter(todo => todo.done)
}
const defalutList = [
{ text: 'star this repository', done: false },
{ text: 'fork this repository', done: false },
{ text: 'follow author', done: false },
{ text: 'vue-element-admin', done: true },
{ text: 'vue', done: true },
{ text: 'element-ui', done: true },
{ text: 'axios', done: true },
{ text: 'webpack', done: true }
]
export default {
components: { Todo },
filters: {
pluralize: (n, w) => n === 1 ? w : w + 's',
capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
},
data() {
return {
visibility: 'all',
filters,
// todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList
todos: defalutList
}
},
computed: {
allChecked() {
return this.todos.every(todo => todo.done)
},
filteredTodos() {
return filters[this.visibility](this.todos)
},
remaining() {
return this.todos.filter(todo => !todo.done).length
}
},
methods: {
setLocalStorage() {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos))
},
addTodo(e) {
const text = e.target.value
if (text.trim()) {
this.todos.push({
text,
done: false
})
this.setLocalStorage()
}
e.target.value = ''
},
toggleTodo(val) {
val.done = !val.done
this.setLocalStorage()
},
deleteTodo(todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
this.setLocalStorage()
},
editTodo({ todo, value }) {
todo.text = value
this.setLocalStorage()
},
clearCompleted() {
this.todos = this.todos.filter(todo => !todo.done)
this.setLocalStorage()
},
toggleAll({ done }) {
this.todos.forEach(todo => {
todo.done = done
this.setLocalStorage()
})
}
}
}
</script>
<style lang="scss">
@import './index.scss';
</style>

View File

@ -0,0 +1,55 @@
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.$_resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
beforeDestroy() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
// to fixed bug when cached by keep-alive
// https://github.com/PanJiaChen/vue-element-admin/issues/2116
activated() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
deactivated() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_initResizeEvent() {
window.addEventListener('resize', this.$_resizeHandler)
},
$_destroyResizeEvent() {
window.removeEventListener('resize', this.$_resizeHandler)
},
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
$_initSidebarResizeEvent() {
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
$_destroySidebarResizeEvent() {
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}
}
}

View File

@ -0,0 +1,176 @@
<template>
<div class="dashboard-editor-container">
<el-row :gutter="12">
<el-col :sm="24" :xs="24" :md="6" :xl="6" :lg="6" :style="{ marginBottom: '12px' }">
<chart-card title="总销售额" total="¥126,560">
<el-tooltip slot="action" class="item" effect="dark" content="指标说明" placement="top-start">
<i class="el-icon-warning-outline" />
</el-tooltip>
<div>
<trend flag="top" style="margin-right: 16px;" rate="12">
<span slot="term">周同比</span>
</trend>
<trend flag="bottom" rate="11">
<span slot="term">日同比</span>
</trend>
</div>
<template slot="footer">日均销售额<span> 234.56</span></template>
</chart-card>
</el-col>
<el-col :sm="24" :xs="24" :md="6" :xl="6" :lg="6" :style="{ marginBottom: '12px' }">
<chart-card title="访问量" :total="8846">
<el-tooltip slot="action" class="item" effect="dark" content="指标说明" placement="top-start">
<i class="el-icon-warning-outline" />
</el-tooltip>
<div>
<mini-area />
</div>
<template slot="footer">日访问量<span> {{ '1234' }}</span></template>
</chart-card>
</el-col>
<el-col :sm="24" :xs="24" :md="6" :xl="6" :lg="6" :style="{ marginBottom: '12px' }">
<chart-card title="支付笔数" :total="6560">
<el-tooltip slot="action" class="item" effect="dark" content="指标说明" placement="top-start">
<i class="el-icon-warning-outline" />
</el-tooltip>
<div>
<mini-bar />
</div>
<template slot="footer">转化率 <span>60%</span></template>
</chart-card>
</el-col>
<el-col :sm="24" :xs="24" :md="6" :xl="6" :lg="6" :style="{ marginBottom: '12px' }">
<chart-card title="运营活动效果" total="78%">
<el-tooltip slot="action" class="item" effect="dark" content="指标说明" placement="top-start">
<i class="el-icon-warning-outline" />
</el-tooltip>
<div>
<mini-progress color="rgb(19, 194, 194)" :target="80" :percentage="78" height="8px" />
</div>
<template slot="footer">
<trend flag="top" style="margin-right: 16px;" rate="12">
<span slot="term">同周比</span>
</trend>
<trend flag="bottom" rate="80">
<span slot="term">日环比</span>
</trend>
</template>
</chart-card>
</el-col>
</el-row>
<el-card :bordered="false" :body-style="{padding: '0'}">
<div class="salesCard">
<el-tabs>
<el-tab-pane label="销售额">
<el-row>
<el-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar :list="barData" title="销售额排行" />
</el-col>
<el-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList" />
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="访问量">
<el-row>
<el-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar :list="barData2" title="销售额趋势" />
</el-col>
<el-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList" />
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</el-card>
</div>
</template>
<script>
import ChartCard from '@/components/ChartCard'
import Trend from '@/components/Trend'
import MiniArea from '@/components/MiniArea'
import MiniBar from '@/components/MiniBar'
import MiniProgress from '@/components/MiniProgress'
import RankList from '@/components/RankList/index'
import Bar from '@/components/Bar.vue'
const barData = []
const barData2 = []
for (let i = 0; i < 12; i += 1) {
barData.push({
x: `${i + 1}`,
y: Math.floor(Math.random() * 1000) + 200
})
barData2.push({
x: `${i + 1}`,
y: Math.floor(Math.random() * 1000) + 200
})
}
const rankList = []
for (let i = 0; i < 7; i++) {
rankList.push({
name: '白鹭岛 ' + (i + 1) + ' 号店',
total: 1234.56 - i * 100
})
}
export default {
name: 'DashboardAdmin',
components: {
ChartCard,
Trend,
MiniArea,
MiniBar,
MiniProgress,
RankList,
Bar
},
data() {
return {
barData,
barData2,
rankList
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.dashboard-editor-container {
padding: 12px;
background-color: rgb(240, 242, 245);
position: relative;
.github-corner {
position: absolute;
top: 0;
border: 0;
right: 0;
}
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
::v-deep .el-tabs__item{
padding-left: 16px!important;
height: 50px;
line-height: 50px;
}
@media (max-width:1024px) {
.chart-wrapper {
padding: 8px;
}
}
</style>

View File

@ -0,0 +1,74 @@
<template>
<div class="dashboard-editor-container">
<div class=" clearfix">
<pan-thumb :image="avatar" style="float: left">
Your roles:
<span v-for="item in roles" :key="item" class="pan-info-roles">{{ item }}</span>
</pan-thumb>
<github-corner style="position: absolute; top: 0px; border: 0; right: 0;" />
<div class="info-container">
<span class="display_name">{{ name }}</span>
<span style="font-size:20px;padding-top:20px;display:inline-block;">Editor's Dashboard</span>
</div>
</div>
<div>
<img :src="emptyGif" class="emptyGif">
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import PanThumb from '@/components/PanThumb'
import GithubCorner from '@/components/GithubCorner'
export default {
name: 'DashboardEditor',
components: { PanThumb, GithubCorner },
data() {
return {
emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3'
}
},
computed: {
...mapGetters([
'name',
'avatar',
'roles'
])
}
}
</script>
<style lang="scss" scoped>
.emptyGif {
display: block;
width: 45%;
margin: 0 auto;
}
.dashboard-editor-container {
background-color: #e3e3e3;
min-height: 100vh;
padding: 50px 60px 0px;
.pan-info-roles {
font-size: 12px;
font-weight: 700;
color: #333;
display: block;
}
.info-container {
position: relative;
margin-left: 190px;
height: 150px;
line-height: 200px;
.display_name {
font-size: 48px;
line-height: 48px;
color: #212121;
position: absolute;
top: 25px;
}
}
}
</style>

View File

@ -0,0 +1,31 @@
<template>
<div class="dashboard-container">
<component :is="currentRole" />
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import adminDashboard from './admin'
import editorDashboard from './editor'
export default {
name: 'Dashboard',
components: { adminDashboard, editorDashboard },
data() {
return {
currentRole: 'adminDashboard'
}
},
computed: {
...mapGetters([
'roles'
])
},
created() {
// if (!this.roles.includes('admin')) {
// this.currentRole = 'editorDashboard'
// }
}
}
</script>

View File

@ -0,0 +1,36 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<div v-loading="loading" :style="'height:'+ height">
<iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
</div>
</el-card>
</template>
</BasicLayout>
</template>
<script>
export default {
components: {
},
data() {
return {
src: process.env.VUE_APP_BASE_API + '/form-generator/index.html',
height: document.documentElement.clientHeight - 94.5 + 'px;',
loading: true
}
},
mounted: function() {
setTimeout(() => {
this.loading = false
}, 230)
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 94.5 + 'px;'
}
}
}
</script>

View File

@ -0,0 +1,101 @@
<template>
<el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="150px">
<el-row>
<el-col :span="12">
<el-form-item prop="tableName">
<span slot="label">
数据表名称
<el-tooltip content="数据库表名称针对gorm对应的table()使用,⚠️这里必须是蛇形结构" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.tableName" placeholder="请输入表名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="tableComment">
<span slot="label">
菜单名称
<el-tooltip content="同步的数据库表名称,生成配置数据时,用作菜单名称" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.tableComment" placeholder="请输入菜单名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="className">
<span slot="label">
结构体模型名称
<el-tooltip content="结构体模型名称代码中的struct名称定义使用" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.className" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="作者名称" prop="functionAuthor">
<el-input v-model="info.functionAuthor" placeholder="请输入作者名称" />
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item prop="isLogicalDelete">
<span slot="label">
是否逻辑删除
<el-tooltip content="目前只支持逻辑删除" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-radio-group v-model="info.isLogicalDelete">
<el-radio label="1"></el-radio>
<el-radio label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="info.isLogicalDelete == '1'" label="逻辑删除字段" prop="logicalDeleteColumn">
<el-input v-model="info.logicalDeleteColumn" placeholder="请输入" />
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="info.remark" type="textarea" :rows="3" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'BasicInfoForm',
props: {
info: {
type: Object,
default: null
}
},
data() {
return {
rules: {
tableName: [
{ required: true, message: '请输入表名称', trigger: 'blur' },
{ pattern: /^[a-z\._]*$/g, trigger: 'blur', message: '只允许小写字母,例如 sys_demo 格式' }
],
tableComment: [
{ required: true, message: '请输入菜单名称', trigger: 'blur' }
],
className: [
{ required: true, message: '请输入模型名称', trigger: 'blur' },
{ pattern: /^[A-Z][A-z0-9]*$/g, trigger: 'blur', message: '必须以大写字母开头,例如 SysDemo 格式' }
],
functionAuthor: [
{ required: true, message: '请输入作者', trigger: 'blur' },
{ pattern: /^[A-Za-z]+$/, trigger: 'blur', message: '校验规则: 只允许输入字母 a-z 或大写 A-Z' }
]
}
}
}
}
</script>

View File

@ -0,0 +1,348 @@
<template>
<el-card>
<el-tabs v-model="activeName">
<el-tab-pane label="基本信息" name="basic">
<basic-info-form ref="basicInfo" :info="info" />
</el-tab-pane>
<el-tab-pane label="字段信息" name="cloum">
<el-alert
title="⚠表字段中的id、create_by、update_by、created_at、updated_at、deleted_at的字段在此列表中已经隐藏"
type="warning"
show-icon
/>
<el-table :data="columns" :max-height="tableHeight" style="width: 100%">
<el-table-column fixed label="序号" type="index" width="50" />
<el-table-column
fixed
label="字段列名"
prop="columnName"
width="150"
:show-overflow-tooltip="true"
/>
<el-table-column fixed label="字段描述" width="150">
<template slot-scope="scope">
<el-input v-model="scope.row.columnComment" />
</template>
</el-table-column>
<el-table-column
label="物理类型"
prop="columnType"
width="120"
:show-overflow-tooltip="true"
/>
<el-table-column label="go类型" width="120">
<template slot-scope="scope">
<el-select v-model="scope.row.goType">
<el-option label="int64" value="int64" />
<el-option label="string" value="string" />
<!-- <el-option label="int" value="int" />
<el-option label="bool" value="bool" /> -->
</el-select>
</template>
</el-table-column>
<el-table-column label="go属性" width="150">
<template slot-scope="scope">
<el-input v-model="scope.row.goField" />
</template>
</el-table-column>
<el-table-column label="json属性" width="150">
<template slot-scope="scope">
<el-input v-model="scope.row.jsonField" />
</template>
</el-table-column>
<el-table-column label="编辑" width="50">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isInsert" true-label="1" false-label="0" />
</template>
</el-table-column>
<!-- <el-table-column label="编辑" width="70" :render-header="renderHeadeUpdate" :cell-style="{'text-align':'center'}">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isEdit" true-label="1" false-label="0" />
</template>
</el-table-column> -->
<el-table-column label="列表" width="70" :render-header="renderHeadeList" :cell-style="{'text-align':'center'}">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isList" true-label="1" false-label="0" />
</template>
</el-table-column>
<el-table-column label="查询" width="70" :render-header="renderHeadeSearch" :cell-style="{'text-align':'center'}">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isQuery" true-label="1" false-label="0" />
</template>
</el-table-column>
<el-table-column label="查询方式" width="120">
<template slot-scope="scope">
<el-select v-model="scope.row.queryType">
<el-option label="=" value="EQ" />
<el-option label="!=" value="NE" />
<el-option label=">" value="GT" />
<el-option label=">=" value="GTE" />
<el-option label="<" value="LT" />
<el-option label="<=" value="LTE" />
<el-option label="LIKE" value="LIKE" />
<!-- <el-option label="BETWEEN" value="BETWEEN" /> -->
</el-select>
</template>
</el-table-column>
<el-table-column label="必填" width="50">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isRequired" true-label="1" />
</template>
</el-table-column>
<el-table-column label="显示类型" width="140">
<template slot-scope="scope">
<el-select v-model="scope.row.htmlType">
<el-option label="文本框" value="input" />
<el-option label="下拉框" value="select" />
<el-option label="单选框" value="radio" />
<!-- <el-option label="文件选择" value="file" /> -->
<!-- <el-option label="复选框" value="checkbox" />
<el-option label="日期控件" value="datetime" />-->
<el-option label="文本域" value="textarea" />
</el-select>
</template>
</el-table-column>
<el-table-column label="字典类型" width="160">
<template slot-scope="scope">
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择">
<el-option
v-for="dict in dictOptions"
:key="dict.dictType"
:label="dict.dictName"
:value="dict.dictType"
>
<span style="float: left">{{ dict.dictName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="关系表" width="160">
<template slot-scope="scope">
<el-select v-model="scope.row.fkTableName" clearable filterable placeholder="请选择" @change="handleChangeConfig(scope.row,scope.$index)">
<el-option
v-for="table in tableTree"
:key="table.tableName"
:label="table.tableName"
:value="table.tableName"
>
<span style="float: left">{{ table.tableName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ table.tableComment }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="关系表key" width="150">
<template slot-scope="scope">
<el-select v-model="scope.row.fkLabelId" clearable filterable placeholder="请选择">
<el-option
v-for="column in scope.row.fkCol"
:key="column.columnName"
:label="column.columnName"
:value="column.jsonField"
>
<span style="float: left">{{ column.jsonField }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ column.columnComment }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="关系表value" width="150">
<template slot-scope="scope">
<el-select v-model="scope.row.fkLabelName" clearable filterable placeholder="请选择">
<el-option
v-for="column in scope.row.fkCol"
:key="column.columnName"
:label="column.columnName"
:value="column.jsonField"
>
<span style="float: left">{{ column.jsonField }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ column.columnComment }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="生成信息" name="genInfo">
<gen-info-form ref="genInfo" :info="info" />
</el-tab-pane>
</el-tabs>
<el-form label-width="100px">
<el-form-item style="text-align: center;margin-left:-100px;margin-top:10px;">
<el-button type="primary" @click="submitForm()">提交</el-button>
<el-button @click="close()">返回</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script>
import { getGenTable, updateGenTable, getTableTree } from '@/api/tools/gen'
// import { listTable } from '@/api/tools/gen'
import { optionselect as getDictOptionselect } from '@/api/admin/dict/type'
import basicInfoForm from './basicInfoForm'
import genInfoForm from './genInfoForm'
export default {
name: 'GenEdit',
components: {
basicInfoForm,
genInfoForm
},
data() {
return {
// 选中选项卡的 name
activeName: 'cloum',
// 表格的高度
tableHeight: document.documentElement.scrollHeight - 245 + 'px',
// 表列信息
columns: [],
tableTree: [],
// 字典信息
dictOptions: [],
// 表详细信息
info: {}
}
},
beforeCreate() {
getTableTree().then(response => {
this.tableTree = response.data
this.tableTree.unshift({ tableId: 0, className: '请选择' })
})
const { tableId } = this.$route.query
if (tableId) {
// 获取表详细信息
getGenTable(tableId).then(res => {
this.columns = res.data.list
this.info = res.data.info
this.info.isDataScope = this.info.isDataScope.toString()
this.info.isActions = this.info.isActions.toString()
this.info.isAuth = this.info.isAuth.toString()
this.columns.forEach(item => {
this.tableTree.filter(function(e) {
if (e.tableId === item.fkTableNameClass) {
item.fkCol = e.columns || [{ columnId: 0, columnName: '请选择' }]
// item.fkCol.unshift({ columnId: 0, columnName: '请选择' })
}
})
})
})
/** 查询字典下拉列表 */
getDictOptionselect().then(response => {
this.dictOptions = response.data
})
}
},
methods: {
renderHeadeUpdate(h, { column, $index }) {
// h 是一个渲染函数 column 是一个对象表示当前列 $index 第几列
return h('div', [
h('span', column.label + ' ', { align: 'center', marginTop: '0px' }),
h(
'el-popover',
{ props: { placement: 'top-start', width: '270', trigger: 'hover' }},
[
h('p', '是否在表单编辑时能够编辑,打√表示需要', { class: 'text-align: center; margin: 0' }),
// 生成 i 标签 添加icon 设置 样式slot 必填
h('i', { class: 'el-icon-question', style: 'color:#ccc,padding-top:5px', slot: 'reference' })
]
)
])
},
renderHeadeList(h, { column, $index }) {
// h 是一个渲染函数 column 是一个对象表示当前列 $index 第几列
return h('div', [
h('span', column.label + ' ', { align: 'center', marginTop: '0px' }),
h(
'el-popover',
{ props: { placement: 'top-start', width: '260', trigger: 'hover' }},
[
h('p', '是否在列表中展示,打√表示需要展示', { class: 'text-align: center; margin: 0' }),
h('i', { class: 'el-icon-question', style: 'color:#ccc,padding-top:5px', slot: 'reference' })
]
)
])
},
renderHeadeSearch(h, { column, $index }) {
return h('div', [
h('span', column.label + ' ', { align: 'center', marginTop: '0px' }),
h(
'el-popover',
{ props: { placement: 'top-start', width: '270', trigger: 'hover' }},
[
h('p', '是都当做搜索条件,打√表示做为搜索条件', { class: 'text-align: center; margin: 0' }),
h('i', { class: 'el-icon-question', style: 'color:#ccc,padding-top:5px', slot: 'reference' })
]
)
])
},
handleChangeConfig(row, index) {
this.tableTree.filter(function(item) {
if (item.tableName === row.fkTableName) {
row.fkCol = item.columns
// row.fkCol.unshift({ columnId: 0, columnName: '请选择' })
}
})
},
/** 提交按钮 */
submitForm() {
const basicForm = this.$refs.basicInfo.$refs.basicInfoForm
const genForm = this.$refs.genInfo.$refs.genInfoForm
Promise.all([basicForm, genForm].map(this.getFormPromise)).then(res => {
const validateResult = res.every(item => !!item)
if (validateResult) {
const genTable = Object.assign({}, basicForm.model, genForm.model)
genTable.columns = this.columns
genTable.params = {
treeCode: genTable.treeCode,
treeName: genTable.treeName,
treeParentCode: genTable.treeParentCode
}
genTable.isDataScope = JSON.parse(genTable.isDataScope)
genTable.isActions = JSON.parse(genTable.isActions)
genTable.isAuth = JSON.parse(genTable.isAuth)
updateGenTable(genTable).then(res => {
this.msgSuccess(res.msg)
if (res.code === 200) {
this.close()
}
})
} else {
this.msgError('表单校验未通过,请重新检查提交内容')
}
})
},
getTables() {
getTableTree().then(response => {
this.tableTree = response.data
this.tableTree.unshift({ tableId: 0, className: '请选择' })
})
},
getTablesCol(tableName) {
return this.tableTree.filter(function(item) {
if (item.tableName === tableName) {
return item.columns
}
})
},
getFormPromise(form) {
return new Promise(resolve => {
form.validate(res => {
resolve(res)
})
})
},
/** 关闭按钮 */
close() {
this.$store.dispatch('tagsView/delView', this.$route)
this.$router.push({ path: '/dev-tools/gen', query: { t: Date.now() }})
}
}
}
</script>

View File

@ -0,0 +1,219 @@
<template>
<el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px">
<el-row>
<el-col :span="12">
<el-form-item prop="tplCategory">
<span slot="label">生成模板</span>
<el-select v-model="info.tplCategory">
<el-option label="关系表(增删改查)" value="crud" />
<!-- <el-option label="关系表(增删改查)" value="mcrud" />
<el-option label="树表(增删改查)" value="tree" /> -->
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="packageName">
<span slot="label">
应用名
<el-tooltip content="应用名例如在app文件夹下将该功能发到那个应用中默认admin" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.packageName" />
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item prop="moduleFrontName">
<span slot="label">
前端文件名
<el-tooltip content="前端项目文件名,例如 sys-user.js " placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.moduleFrontName" />
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item prop="businessName">
<span slot="label">
业务名
<el-tooltip content="可理解为功能英文名,例如 user" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.businessName" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="functionName">
<span slot="label">
功能描述
<el-tooltip content="同步的数据库表备注,用作类描述,例如:用户" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.functionName" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="moduleName">
<span slot="label">
接口路径
<el-tooltip content="接口路径例如api/v1/{sys-user}" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input v-model="info.moduleName">
<template slot="prepend">api/{version}/</template>
<template slot="append">...</template>
</el-input>
</el-form-item>
<!-- <el-alert
title="接口地址示例"
description="[get]api/{version}/{接口路径} \r\n [post]"
type="success"
show-icon
/> -->
</el-col>
<!-- <el-col :span="12">
<el-form-item prop="isDataScope">
<span slot="label">
是否认证
<el-tooltip content="是指是否使用用户和角色验证中间件" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-select v-model="info.isAuth">
<el-option label="true" value="1" />
<el-option label="false" value="2" />
</el-select>
</el-form-item>
</el-col> -->
<!-- <el-col :span="12">
<el-form-item prop="isDataScope">
<span slot="label">
数据权限
<el-tooltip content="暂不支持" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-select v-model="info.isDataScope" disabled>
<el-option label="true" value="1" />
<el-option label="false" value="2" />
</el-select>
</el-form-item>
</el-col> -->
<!-- <el-col :span="12">
<el-form-item prop="isActions">
<span slot="label">
是否actions
<el-tooltip content="系统通用增删改查中间件方法" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-select v-model="info.isActions" disabled>
<el-option label="false" value="2" />
</el-select>
</el-form-item>
</el-col> -->
</el-row>
<el-row v-show="info.tplCategory == 'tree'">
<h4 class="form-header">其他信息</h4>
<el-col :span="12">
<el-form-item>
<span slot="label">
树编码字段
<el-tooltip content="树显示的编码字段名, 如dept_id" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-select v-model="info.treeCode" placeholder="请选择">
<el-option
v-for="column in info.columns"
:key="column.columnName"
:label="column.columnName + '' + column.columnComment"
:value="column.columnName"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item>
<span slot="label">
树父编码字段
<el-tooltip content="树显示的父编码字段名, 如parent_Id" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-select v-model="info.treeParentCode" placeholder="请选择">
<el-option
v-for="column in info.columns"
:key="column.columnName"
:label="column.columnName + '' + column.columnComment"
:value="column.columnName"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item>
<span slot="label">
树名称字段
<el-tooltip content="树节点的显示名称字段名, 如dept_name" placement="top">
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-select v-model="info.treeName" placeholder="请选择">
<el-option
v-for="column in info.columns"
:key="column.columnName"
:label="column.columnName + '' + column.columnComment"
:value="column.columnName"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'BasicInfoForm',
props: {
info: {
type: Object,
default: null
}
},
data() {
return {
rules: {
tplCategory: [
{ required: true, message: '请选择生成模板', trigger: 'blur' }
],
packageName: [
{ required: true, message: '请输入生成包路径', trigger: 'blur' },
{ pattern: /^[a-z]*$/g, trigger: 'blur', message: '只允许小写字母,例如 system 格式' }
],
moduleName: [
{ required: true, message: '请输入生成模块名', trigger: 'blur' },
{ pattern: /^[a-z\-]*[a-z]$/g, trigger: 'blur', message: '只允许小写字母,例如 sys-demo 格式' }
],
businessName: [
{ required: true, message: '请输入生成业务名', trigger: 'blur' },
{ pattern: /^[a-z][A-Za-z]+$/, trigger: 'blur', message: '校验规则: 只允许输入字母 a-z 或大写 A-Z ,并且小写字母开头' }
],
functionName: [
{ required: true, message: '请输入生成功能名', trigger: 'blur' }
]
}
}
},
created() {}
}
</script>

View File

@ -0,0 +1,121 @@
<template>
<!-- 导入表 -->
<el-dialog title="导入表" :visible.sync="visible" width="800px" top="5vh">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item label="表名称" prop="tableName">
<el-input
v-model="queryParams.tableName"
placeholder="请输入表名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="表描述" prop="tableComment">
<el-input
v-model="queryParams.tableComment"
placeholder="请输入表描述"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row>
<el-table ref="table" :data="dbTableList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="tableName" label="表名称" />
<el-table-column prop="tableComment" label="表描述" />
<el-table-column prop="createdAt" label="创建时间" />
<el-table-column prop="updatedAt" label="更新时间" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="loading" @click="handleImportTable"> </el-button>
<el-button @click="visible = false"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { listDbTable, importTable } from '@/api/tools/gen'
export default {
data() {
return {
loading: false,
// 遮罩层
visible: false,
// 选中数组值
tables: [],
// 总条数
total: 0,
// 表数据
dbTableList: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
tableName: undefined,
tableComment: undefined
}
}
},
methods: {
// 显示弹框
show() {
this.getList()
this.visible = true
},
clickRow(row) {
this.$refs.table.toggleRowSelection(row)
},
// 多选框选中数据
handleSelectionChange(selection) {
this.tables = selection.map(item => item.tableName)
},
// 查询表数据
getList() {
listDbTable(this.queryParams).then(res => {
if (res.code === 200) {
this.dbTableList = res.data.list
this.total = res.data.count
}
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
/** 导入按钮操作 */
handleImportTable() {
this.loading = true
this.visible = true
importTable({ tables: this.tables.join(',') }).then(res => {
this.msgSuccess(res.msg)
if (res.code === 200) {
this.visible = false
this.$emit('ok')
}
this.loading = false
})
}
}
}
</script>

View File

@ -0,0 +1,421 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-position="left">
<el-form-item label="表名称" prop="tableName">
<el-input
v-model="queryParams.tableName"
placeholder="请输入表名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="菜单名称" prop="tableComment">
<el-input
v-model="queryParams.tableComment"
placeholder="请输入菜单名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-button
type="primary"
icon="el-icon-download"
size="mini"
@click="handleGenTable"
>生成</el-button> -->
</el-col>
<el-col :span="1.5">
<el-button
type="info"
icon="el-icon-upload"
size="mini"
@click="openImportTable"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleEditTable"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="序号" align="center" prop="tableId" width="50px" />
<el-table-column
label="表名称"
align="center"
prop="tableName"
:show-overflow-tooltip="true"
width="130"
/>
<el-table-column
label="菜单名称"
align="center"
prop="tableComment"
:show-overflow-tooltip="true"
width="130"
/>
<el-table-column
label="模型名称"
align="center"
prop="className"
:show-overflow-tooltip="true"
width="130"
/>
<el-table-column label="创建时间" align="center" prop="createdAt" width="165">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
type="text"
size="small"
icon="el-icon-edit"
@click="handleEditTable(scope.row)"
>编辑</el-button>
<el-button
type="text"
size="small"
icon="el-icon-view"
@click="handlePreview(scope.row)"
>预览</el-button>
<el-button
slot="reference"
type="text"
size="small"
icon="el-icon-view"
@click="handleToProject(scope.row)"
>代码生成</el-button>
<el-button
slot="reference"
type="text"
size="small"
icon="el-icon-view"
@click="handleToDB(scope.row)"
>生成配置</el-button>
<el-button
slot="reference"
type="text"
size="small"
icon="el-icon-view"
@click="handleToApiFile(scope.row)"
>生成迁移脚本</el-button>
<el-button
slot="reference"
type="text"
size="small"
icon="el-icon-delete"
@click="handleSingleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-card>
<!-- 预览界面 -->
<el-dialog class="preview" :title="preview.title" :visible.sync="preview.open" :close-on-click-modal="false" fullscreen>
<div class="el-dialog-container">
<div class="tag-group">
<!-- eslint-disable-next-line vue/valid-v-for -->
<el-tag v-for="(value, key) in preview.data" @click="codeChange(key)">
<template>
{{ key.substring(key.lastIndexOf('/')+1,key.indexOf('.go.template')) }}
</template>
</el-tag>
</div>
<div id="codemirror">
<codemirror ref="cmEditor" :value="codestr" :options="cmOptions" />
</div>
<!-- <el-tabs v-model="preview.activeName" tab-position="left">
<el-tab-pane
v-for="(value, key) in preview.data"
:key="key"
:label="key.substring(key.lastIndexOf('/')+1,key.indexOf('.template'))"
:name="key.substring(key.lastIndexOf('/')+1,key.indexOf('.template'))"
>
<pre class="pre"/>
</el-tab-pane>
</el-tabs> -->
</div>
</el-dialog>
<import-table ref="importTB" @ok="handleQuery" />
</template>
</BasicLayout>
</template>
<script>
import { listTable, previewTable, delTable, toDBTable, toProjectTableCheckRole, apiToFile } from '@/api/tools/gen'
import importTable from './importTable'
import { downLoadFile } from '@/utils/zipdownload'
import { codemirror } from 'vue-codemirror'
import 'codemirror/theme/material-palenight.css'
require('codemirror/mode/javascript/javascript')
import 'codemirror/mode/javascript/javascript'
import 'codemirror/mode/go/go'
import 'codemirror/mode/vue/vue'
export default {
name: 'Gen',
components: { importTable, codemirror },
data() {
return {
cmOptions: {
tabSize: 4,
theme: 'material-palenight',
mode: 'text/javascript',
lineNumbers: true,
line: true
// more CodeMirror options...
},
codestr: '',
// 遮罩层
loading: true,
// 唯一标识符
uniqueId: '',
// 选中数组
ids: [],
// 选中表数组
tableNames: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 表数据
tableList: [],
// 日期范围
dateRange: '',
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
tableName: undefined,
tableComment: undefined
},
// 预览参数
preview: {
open: false,
title: '代码预览',
data: {},
activeName: 'api.go'
}
}
},
created() {
this.getList()
},
activated() {
const time = this.$route.query.t
if (time !== null && time !== this.uniqueId) {
this.uniqueId = time
this.resetQuery()
}
},
methods: {
/** 查询表集合 */
getList() {
this.loading = true
listTable(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.tableList = response.data.list
this.total = response.data.count
this.loading = false
}
)
},
codeChange(e) {
if (e.indexOf('js') > -1) {
this.cmOptions.mode = 'text/javascript'
}
if (e.indexOf('model') > -1 || e.indexOf('router') > -1 || e.indexOf('api') > -1 || e.indexOf('service') > -1 || e.indexOf('dto') > -1) {
this.cmOptions.mode = 'text/x-go'
}
if (e.indexOf('vue') > -1) {
this.cmOptions.mode = 'text/x-vue'
}
this.codestr = this.preview.data[e]
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 生成代码操作 */
handleGenTable(row) {
const ids = row.tableId || this.ids
if (ids === '') {
this.msgError('请选择要生成的数据')
return
}
downLoadFile('/api/v1/gen/gencode/' + ids)
},
/** 打开导入表弹窗 */
openImportTable() {
this.$refs.importTB.show()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 预览按钮 */
handlePreview(row) {
previewTable(row.tableId).then(response => {
this.preview.data = response.data
this.preview.open = true
this.codeChange('template/api.go.template')
})
},
handleToProject(row) {
toProjectTableCheckRole(row.tableId, false).then((response) => {
this.msgSuccess(response.msg)
}).catch(function() {})
},
handleToApiFile(row) {
apiToFile(row.tableId, true).then((response) => {
this.msgSuccess(response.msg)
}).catch(function() {})
},
handleToDB(row) {
toDBTable(row.tableId).then((response) => {
this.msgSuccess(response.msg)
}).catch(function() {})
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.tableId)
this.tableNames = selection.map(item => item.tableName)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleEditTable(row) {
const tableId = row.tableId || this.ids[0]
this.$router.push({ path: '/dev-tools/editTable', query: { tableId: tableId }})
},
/** 删除按钮操作 */
handleDelete(row) {
const tableIds = row.tableId || this.ids
this.$confirm('是否确认删除表编号为"' + tableIds + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delTable(tableIds)
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
handleSingleDelete(row) {
const tableIds = row.tableId || this.ids
delTable(tableIds).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
}
}
}
</script>
<style lang="scss" scoped>
.el-dialog-container ::v-deep{
overflow: hidden;
.el-scrollbar__view{
height: 100%;
}
.pre{
height: 546px;
overflow: hidden;
.el-scrollbar{
height: 100%;
}
}
.el-scrollbar__wrap::-webkit-scrollbar{
display: none;
}
}
::v-deep .el-dialog__body{
padding: 0 20px;
margin:0;
}
.tag-group {
margin: 0 0 10px -10px;
}
.tag-group .el-tag{
margin-left: 10px;
}
.el-tag {
cursor: pointer;
}
</style>
<style lang="scss">
#codemirror {
height: auto;
margin: 0;
overflow: auto;
}
.CodeMirror {
border: 1px solid #eee;
height: 600px;
}
</style>

View File

@ -0,0 +1,38 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<div v-loading="loading" :style="'height:' + height">
<iframe
:src="src"
frameborder="no"
style="width: 100%; height: 100%"
scrolling="auto"
/>
</div>
</el-card>
</template>
</BasicLayout>
</template>
<script>
export default {
name: 'Swagger',
components: {},
data() {
return {
src: process.env.VUE_APP_BASE_API + '/swagger/admin/index.html',
height: document.documentElement.clientHeight - 94.5 + 'px;',
loading: true
}
},
mounted: function() {
setTimeout(() => {
this.loading = false
}, 230)
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 94.5 + 'px;'
}
}
}
</script>

View File

@ -0,0 +1,99 @@
<template>
<div class="errPage-container">
<el-button icon="el-icon-arrow-left" class="pan-back-btn" @click="back">
返回
</el-button>
<el-row>
<el-col :span="12">
<h1 class="text-jumbo text-ginormous">
Oops!
</h1>
gif来源<a href="https://zh.airbnb.com/" target="_blank">airbnb</a> 页面
<h2>你没有权限去该页面</h2>
<h6>如有不满请联系你领导</h6>
<ul class="list-unstyled">
<li>或者你可以去:</li>
<li class="link-type">
<router-link to="/dashboard">
回首页
</router-link>
</li>
<li class="link-type">
<a href="https://www.taobao.com/">随便看看</a>
</li>
<li><a href="#" @click.prevent="dialogVisible=true">点我看图</a></li>
</ul>
</el-col>
<el-col :span="12">
<img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream.">
</el-col>
</el-row>
<el-dialog :visible.sync="dialogVisible" title="随便看" :close-on-click-modal="false">
<img :src="ewizardClap" class="pan-img">
</el-dialog>
</div>
</template>
<script>
import errGif from '@/assets/401_images/401.gif'
export default {
name: 'Page401',
data() {
return {
errGif: errGif + '?' + +new Date(),
ewizardClap: 'https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646',
dialogVisible: false
}
},
methods: {
back() {
if (this.$route.query.noGoBack) {
this.$router.push({ path: '/dashboard' })
} else {
this.$router.go(-1)
}
}
}
}
</script>
<style lang="scss" scoped>
.errPage-container {
width: 800px;
max-width: 100%;
margin: 100px auto;
.pan-back-btn {
background: #008489;
color: #fff;
border: none!important;
}
.pan-gif {
margin: 0 auto;
display: block;
}
.pan-img {
display: block;
margin: 0 auto;
width: 100%;
}
.text-jumbo {
font-size: 60px;
font-weight: 700;
color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
}
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
</style>

View File

@ -0,0 +1,228 @@
<template>
<div class="wscn-http404-container">
<div class="wscn-http404">
<div class="pic-404">
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
</div>
<div class="bullshit">
<div class="bullshit__oops">OOPS!</div>
<div class="bullshit__info">All rights reserved
<a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
</div>
<div class="bullshit__headline">{{ message }}</div>
<div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
<a href="" class="bullshit__return-home">Back to home</a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Page404',
computed: {
message() {
return 'The webmaster said that you can not enter this page...'
}
}
}
</script>
<style lang="scss" scoped>
.wscn-http404-container{
transform: translate(-50%,-50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #222;
font-weight: bold;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<div style="display:inline-block;">
<label class="radio-label">Cell Auto-Width: </label>
<el-radio-group v-model="autoWidth">
<el-radio :label="true" border>
True
</el-radio>
<el-radio :label="false" border>
False
</el-radio>
</el-radio-group>
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: true
}
},
computed: {
autoWidth: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

View File

@ -0,0 +1,39 @@
<template>
<div style="display:inline-block;">
<label class="radio-label">Book Type: </label>
<el-select v-model="bookType" style="width:120px;">
<el-option
v-for="item in options"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: 'xlsx'
}
},
data() {
return {
options: ['xlsx', 'csv', 'txt']
}
},
computed: {
bookType: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

View File

@ -0,0 +1,27 @@
<template>
<div style="display:inline-block;">
<label class="radio-label" style="padding-left:0;">Filename: </label>
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:345px;" prefix-icon="el-icon-document" />
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
}
},
computed: {
filename: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

View File

@ -0,0 +1,42 @@
<template>
<div class="app-container">
<upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" />
<el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;">
<el-table-column v-for="item of tableHeader" :key="item" :prop="item" :label="item" />
</el-table>
</div>
</template>
<script>
import UploadExcelComponent from '@/components/UploadExcel/index.vue'
export default {
name: 'UploadExcel',
components: { UploadExcelComponent },
data() {
return {
tableData: [],
tableHeader: []
}
},
methods: {
beforeUpload(file) {
const isLt1M = file.size / 1024 / 1024 < 10
if (isLt1M) {
return true
}
this.$message({
message: 'Please do not upload files larger than 1m in size.',
type: 'warning'
})
return false
},
handleSuccess({ results, header }) {
this.tableData = results
this.tableHeader = header
}
}
}
</script>

3
src/views/log/index.vue Normal file
View File

@ -0,0 +1,3 @@
<template>
<router-view />
</template>

View File

@ -0,0 +1,15 @@
<script>
export default {
name: 'AuthRedirect',
created() {
const hash = window.location.search.slice(1)
if (window.localStorage) {
window.localStorage.setItem('x-admin-oauth-code', hash)
window.close()
}
},
render: function(h) {
return h() // avoid warning message
}
}
</script>

View File

@ -0,0 +1,72 @@
<template>
<div class="social-signup-container">
<div class="sign-btn" @click="wechatHandleClick('wechat')">
<span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span>
WeChat
</div>
<div class="sign-btn" @click="tencentHandleClick('tencent')">
<span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span>
QQ
</div>
</div>
</template>
<script>
// import openWindow from '@/utils/open-window'
export default {
name: 'SocialSignin',
methods: {
wechatHandleClick(thirdpart) {
alert('ok')
// this.$store.commit('SET_AUTH_TYPE', thirdpart)
// const appid = 'xxxxx'
// const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect')
// const url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&response_type=code&scope=snsapi_login#wechat_redirect'
// openWindow(url, thirdpart, 540, 540)
},
tencentHandleClick(thirdpart) {
alert('ok')
// this.$store.commit('SET_AUTH_TYPE', thirdpart)
// const client_id = 'xxxxx'
// const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect')
// const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri
// openWindow(url, thirdpart, 540, 540)
}
}
}
</script>
<style lang="scss" scoped>
.social-signup-container {
margin: 20px 0;
.sign-btn {
display: inline-block;
cursor: pointer;
}
.icon {
color: #fff;
font-size: 24px;
margin-top: 8px;
}
.wx-svg-container,
.qq-svg-container {
display: inline-block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
padding-top: 1px;
border-radius: 4px;
margin-bottom: 20px;
margin-right: 5px;
}
.wx-svg-container {
background-color: #24da70;
}
.qq-svg-container {
background-color: #6BA2D6;
margin-left: 50px;
}
}
</style>

690
src/views/login/index.vue Normal file
View File

@ -0,0 +1,690 @@
<template>
<div class="login-container">
<div id="particles-js">
<!-- <vue-particles
v-if="refreshParticles"
color="#dedede"
:particle-opacity="0.7"
:particles-number="80"
shape-type="circle"
:particle-size="4"
lines-color="#dedede"
:lines-width="1"
:line-linked="true"
:line-opacity="0.4"
:lines-distance="150"
:move-speed="3"
:hover-effect="true"
hover-mode="grab"
:click-effect="true"
click-mode="push"
/> -->
</div>
<div class="login-weaper animated bounceInDown">
<div class="login-left">
<div class="login-time" v-text="currentTime" />
<img :src="sysInfo.sys_app_logo" alt="" class="img">
<p class="title" v-text="sysInfo.sys_app_name" />
</div>
<div class="login-border">
<div class="login-main">
<div class="login-title">用户登录</div>
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
autocomplete="on"
label-position="left"
>
<el-form-item prop="username">
<span class="svg-container">
<i class="el-icon-user" />
</span>
<el-input
ref="username"
v-model="loginForm.username"
placeholder="用户名"
name="username"
type="text"
tabindex="1"
autocomplete="on"
/>
</el-form-item>
<el-tooltip
v-model="capsTooltip"
content="Caps lock is On"
placement="right"
manual
>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
:type="passwordType"
placeholder="密码"
name="password"
tabindex="2"
autocomplete="on"
@keyup.native="checkCapslock"
@blur="capsTooltip = false"
@keyup.enter.native="handleLogin"
/>
<span class="show-pwd" @click="showPwd">
<svg-icon
:icon-class="
passwordType === 'password' ? 'eye' : 'eye-open'
"
/>
</span>
</el-form-item>
</el-tooltip>
<el-form-item prop="code" style="width: 66%; float: left">
<span class="svg-container">
<svg-icon icon-class="validCode" />
</span>
<el-input
ref="username"
v-model="loginForm.code"
placeholder="验证码"
name="username"
type="text"
tabindex="3"
maxlength="5"
autocomplete="off"
style="width: 75%"
@keyup.enter.native="handleLogin"
/>
</el-form-item>
<div
class="login-code"
style="
cursor: pointer;
width: 30%;
height: 48px;
float: right;
background-color: #f0f1f5;
"
>
<img
style="
height: 48px;
width: 100%;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 5px;
"
:src="codeUrl"
@click="getCode"
>
</div>
<el-button
:loading="loading"
type="primary"
style="width: 100%; padding: 12px 20px; margin-bottom: 30px"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
</el-form>
</div>
</div>
</div>
<el-dialog title="Or connect with" :visible.sync="showDialog" :close-on-click-modal="false">
Can not be simulated on local, so please combine you own business
simulation! ! !
<br>
<br>
<br>
<social-sign />
</el-dialog>
<div
id="bottom_layer"
class="s-bottom-layer s-isindex-wrap"
style="visibility: visible; width: 100%"
>
<div class="s-bottom-layer-content">
<div class="lh">
<a class="text-color" href="https://beian.miit.gov.cn" target="_blank">
沪ICP备XXXXXXXXX号-1
</a>
</div>
<div class="open-content-info">
<div class="tip-hover-panel" style="top: -18px; right: -12px">
<div class="rest_info_tip">
<div class="tip-wrapper">
<div class="lh tip-item" style="display: none">
<a
class="text-color"
href="https://beian.miit.gov.cn"
target="_blank"
>
沪ICP备XXXXXXXXX号-1
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getCodeImg } from '@/api/login'
import moment from 'moment'
import SocialSign from './components/SocialSignin'
export default {
name: 'Login',
components: { SocialSign },
data() {
return {
codeUrl: '',
cookiePassword: '',
refreshParticles: true,
loginForm: {
username: '',
password: '',
rememberMe: false,
code: '',
uuid: ''
},
loginRules: {
username: [
{ required: true, trigger: 'blur', message: '用户名不能为空' }
],
password: [
{ required: true, trigger: 'blur', message: '密码不能为空' }
],
code: [
{ required: true, trigger: 'change', message: '验证码不能为空' }
]
},
passwordType: 'password',
capsTooltip: false,
loading: false,
showDialog: false,
redirect: undefined,
otherQuery: {},
currentTime: null,
sysInfo: ''
}
},
watch: {
$route: {
handler: function(route) {
const query = route.query
if (query) {
this.redirect = query.redirect
this.otherQuery = this.getOtherQuery(query)
}
},
immediate: true
}
},
created() {
this.getCode()
// window.addEventListener('storage', this.afterQRScan)
this.getCurrentTime()
this.getSystemSetting()
},
mounted() {
if (this.loginForm.username === '') {
this.$refs.username.focus()
} else if (this.loginForm.password === '') {
this.$refs.password.focus()
}
window.addEventListener('resize', () => {
this.refreshParticles = false
this.$nextTick(() => (this.refreshParticles = true))
})
},
destroyed() {
clearInterval(this.timer)
window.removeEventListener('resize', () => {})
// window.removeEventListener('storage', this.afterQRScan)
},
methods: {
getSystemSetting() {
this.$store.dispatch('system/settingDetail').then((ret) => {
this.sysInfo = ret
document.title = ret.sys_app_name
})
},
getCurrentTime() {
this.timer = setInterval((_) => {
this.currentTime = moment().format('YYYY-MM-DD HH时mm分ss秒')
}, 1000)
},
getCode() {
getCodeImg().then((res) => {
if (res !== undefined) {
this.codeUrl = res.data
this.loginForm.uuid = res.id
}
})
},
checkCapslock({ shiftKey, key } = {}) {
if (key && key.length === 1) {
if (
(shiftKey && key >= 'a' && key <= 'z') ||
(!shiftKey && key >= 'A' && key <= 'Z')
) {
this.capsTooltip = true
} else {
this.capsTooltip = false
}
}
if (key === 'CapsLock' && this.capsTooltip === true) {
this.capsTooltip = false
}
},
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus()
})
},
handleLogin() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true
this.$store
.dispatch('user/login', this.loginForm)
.then(() => {
this.$router
.push({ path: this.redirect || '/admin/line-pre-order', query: this.otherQuery })
.catch(() => {})
})
.catch(() => {
this.loading = false
this.getCode()
})
} else {
console.log('error submit!!')
return false
}
})
},
getOtherQuery(query) {
return Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
}
return acc
}, {})
}
}
}
</script>
<style lang="scss" scoped>
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg: #283443;
$light_gray: #fff;
$cursor: #fff;
#bottom_layer {
visibility: hidden;
width: 3000px;
position: fixed;
z-index: 302;
bottom: 0;
left: 0;
height: 39px;
padding-top: 1px;
zoom: 1;
margin: 0;
line-height: 39px;
// background: #0e6cff;
}
#bottom_layer .lh {
display: inline-block;
margin-right: 14px;
}
#bottom_layer .lh .emphasize {
text-decoration: underline;
font-weight: 700;
}
#bottom_layer .lh:last-child {
margin-left: -2px;
margin-right: 0;
}
#bottom_layer .lh.activity {
font-weight: 700;
text-decoration: underline;
}
#bottom_layer a {
font-size: 12px;
text-decoration: none;
}
#bottom_layer .text-color {
color: #bbb;
}
#bottom_layer .aria-img {
width: 49px;
height: 20px;
margin-bottom: -5px;
}
#bottom_layer a:hover {
color: #fff;
}
#bottom_layer .s-bottom-layer-content {
margin: 0 17px;
text-align: center;
}
#bottom_layer .s-bottom-layer-content .auto-transform-line {
display: inline;
}
#bottom_layer .s-bottom-layer-content .auto-transform-line:first-child {
margin-right: 14px;
}
.s-bottom-space {
position: static;
width: 100%;
height: 40px;
margin: 23px auto 12px;
}
#bottom_layer .open-content-info a:hover {
color: #fff;
}
#bottom_layer .open-content-info .text-color {
color: #626675;
}
.open-content-info {
position: relative;
display: inline-block;
width: 20px;
}
.open-content-info > span {
cursor: pointer;
font-size: 14px;
}
.open-content-info > span:hover {
color: #fff;
}
.open-content-info .tip-hover-panel {
position: absolute;
display: none;
padding-bottom: 18px;
}
.open-content-info .tip-hover-panel .rest_info_tip {
max-width: 560px;
padding: 8px 12px 8px 12px;
background: #fff;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.05);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
text-align: left;
}
.open-content-info .tip-hover-panel .rest_info_tip .tip-wrapper {
white-space: nowrap;
line-height: 20px;
}
.open-content-info .tip-hover-panel .rest_info_tip .tip-wrapper .tip-item {
height: 20px;
line-height: 20px;
}
.open-content-info
.tip-hover-panel
.rest_info_tip
.tip-wrapper
.tip-item:last-child {
margin-right: 0;
}
@media screen and (max-width: 515px) {
.open-content-info {
width: 16px;
}
.open-content-info .tip-hover-panel {
right: -16px !important;
}
}
.footer {
background-color: #0e6cff;
margin-bottom: -20px;
}
.login-container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
height: 100%;
margin: 0 auto;
background: url("../../assets/login.png") no-repeat;
background-color: #0e6cff;
position: relative;
background-size: cover;
height: 100vh;
background-position: 50%;
}
#particles-js {
z-index: 1;
width: 100%;
height: 100%;
position: absolute;
}
.login-weaper {
margin: 0 auto;
width: 1000px;
-webkit-box-shadow: -4px 5px 10px rgba(0, 0, 0, 0.4);
box-shadow: -4px 5px 10px rgba(0, 0, 0, 0.4);
z-index: 1000;
}
.login-left {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
background-color: rgba(64, 158, 255, 0);
color: #fff;
float: left;
width: 50%;
position: relative;
min-height: 500px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
.login-time {
position: absolute;
left: 25px;
top: 25px;
width: 100%;
color: #fff;
opacity: 0.9;
font-size: 18px;
overflow: hidden;
font-weight: 500;
}
}
.login-left .img {
width: 90px;
height: 90px;
border-radius: 3px;
}
.login-left .title {
text-align: center;
color: #fff;
letter-spacing: 2px;
font-size: 16px;
font-weight: 600;
}
.login-border {
position: relative;
min-height: 500px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
border-left: none;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
color: #fff;
background-color: hsla(0, 0%, 100%, 0.9);
width: 50%;
float: left;
}
.login-main {
margin: 0 auto;
width: 65%;
}
.login-title {
color: #333;
margin-bottom: 40px;
font-weight: 500;
font-size: 22px;
text-align: center;
letter-spacing: 4px;
}
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* reset element-ui css */
.login-container {
::v-deep .el-input {
display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: #333;
height: 47px;
caret-color: #333;
&:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: $cursor !important;
}
}
}
.el-form-item {
border: 1px solid rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.8);
border-radius: 5px;
color: #454545;
}
}
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
.thirdparty-button {
position: absolute;
right: 0;
bottom: 6px;
}
@media only screen and (max-width: 470px) {
.thirdparty-button {
display: none;
}
.login-weaper {
width: 100%;
padding: 0 30px;
box-sizing: border-box;
box-shadow: none;
}
.login-main {
width: 80%;
}
.login-left {
display: none !important;
}
.login-border {
width: 100%;
}
}
}
</style>

View File

@ -0,0 +1,38 @@
<template>
<el-form>
<el-form-item label="Name">
<el-input v-model.trim="user.name" />
</el-form-item>
<el-form-item label="Email">
<el-input v-model.trim="user.email" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">Update</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
user: {
type: Object,
default: () => {
return {
name: '',
email: ''
}
}
}
},
methods: {
submit() {
this.$message({
message: 'User information has been updated successfully',
type: 'success',
duration: 5 * 1000
})
}
}
}
</script>

View File

@ -0,0 +1,185 @@
<template>
<div class="user-activity">
<div class="post">
<div class="user-block">
<img class="img-circle" :src="'https://wpimg.wallstcn.com/57ed425a-c71e-4201-9428-68760c0537c4.jpg'+avatarPrefix">
<span class="username text-muted">Iron Man</span>
<span class="description">Shared publicly - 7:30 PM today</span>
</div>
<p>
Lorem ipsum represents a long-held tradition for designers,
typographers and the like. Some people hate it and argue for
its demise, but others ignore the hate as they create awesome
tools to help create filler text for everyone from bacon lovers
to Charlie Sheen fans.
</p>
<ul class="list-inline">
<li>
<span class="link-black text-sm">
<i class="el-icon-share" />
Share
</span>
</li>
<li>
<span class="link-black text-sm">
<svg-icon icon-class="like" />
Like
</span>
</li>
</ul>
</div>
<div class="post">
<div class="user-block">
<img class="img-circle" :src="'https://wpimg.wallstcn.com/9e2a5d0a-bd5b-457f-ac8e-86554616c87b.jpg'+avatarPrefix">
<span class="username text-muted">Captain American</span>
<span class="description">Sent you a message - yesterday</span>
</div>
<p>
Lorem ipsum represents a long-held tradition for designers,
typographers and the like. Some people hate it and argue for
its demise, but others ignore the hate as they create awesome
tools to help create filler text for everyone from bacon lovers
to Charlie Sheen fans.
</p>
<ul class="list-inline">
<li>
<span class="link-black text-sm">
<i class="el-icon-share" />
Share
</span>
</li>
<li>
<span class="link-black text-sm">
<svg-icon icon-class="like" />
Like
</span>
</li>
</ul>
</div>
<div class="post">
<div class="user-block">
<img class="img-circle" :src="'https://wpimg.wallstcn.com/fb57f689-e1ab-443c-af12-8d4066e202e2.jpg'+avatarPrefix">
<span class="username">Spider Man</span>
<span class="description">Posted 4 photos - 2 days ago</span>
</div>
<div class="user-images">
<el-carousel :interval="6000" type="card" height="220px">
<el-carousel-item v-for="item in carouselImages" :key="item">
<img :src="item+carouselPrefix" class="image">
</el-carousel-item>
</el-carousel>
</div>
<ul class="list-inline">
<li><span class="link-black text-sm"><i class="el-icon-share" /> Share</span></li>
<li>
<span class="link-black text-sm">
<svg-icon icon-class="like" /> Like</span>
</li>
</ul>
</div>
</div>
</template>
<script>
const avatarPrefix = '?imageView2/1/w/80/h/80'
const carouselPrefix = '?imageView2/2/h/440'
export default {
data() {
return {
carouselImages: [
'https://wpimg.wallstcn.com/9679ffb0-9e0b-4451-9916-e21992218054.jpg',
'https://wpimg.wallstcn.com/bcce3734-0837-4b9f-9261-351ef384f75a.jpg',
'https://wpimg.wallstcn.com/d1d7b033-d75e-4cd6-ae39-fcd5f1c0a7c5.jpg',
'https://wpimg.wallstcn.com/50530061-851b-4ca5-9dc5-2fead928a939.jpg'
],
avatarPrefix,
carouselPrefix
}
}
}
</script>
<style lang="scss" scoped>
.user-activity {
.user-block {
.username,
.description {
display: block;
margin-left: 50px;
padding: 2px 0;
}
.username{
font-size: 16px;
color: #000;
}
:after {
clear: both;
}
.img-circle {
border-radius: 50%;
width: 40px;
height: 40px;
float: left;
}
span {
font-weight: 500;
font-size: 12px;
}
}
.post {
font-size: 14px;
border-bottom: 1px solid #d2d6de;
margin-bottom: 15px;
padding-bottom: 15px;
color: #666;
.image {
width: 100%;
height: 100%;
}
.user-images {
padding-top: 20px;
}
}
.list-inline {
padding-left: 0;
margin-left: -5px;
list-style: none;
li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
font-size: 13px;
}
.link-black {
&:hover,
&:focus {
color: #999;
}
}
}
}
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
</style>

View File

@ -0,0 +1,43 @@
<template>
<div class="block">
<el-timeline>
<el-timeline-item v-for="(item,index) of timeline" :key="index" :timestamp="item.timestamp" placement="top">
<el-card>
<h4>{{ item.title }}</h4>
<p>{{ item.content }}</p>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</template>
<script>
export default {
data() {
return {
timeline: [
{
timestamp: '2019/4/20',
title: 'Update Github template',
content: 'PanJiaChen committed 2019/4/20 20:46'
},
{
timestamp: '2019/4/21',
title: 'Update Github template',
content: 'PanJiaChen committed 2019/4/21 20:46'
},
{
timestamp: '2019/4/22',
title: 'Build Template',
content: 'PanJiaChen committed 2019/4/22 20:46'
},
{
timestamp: '2019/4/23',
title: 'Release New Version',
content: 'PanJiaChen committed 2019/4/23 20:46'
}
]
}
}
}
</script>

View File

@ -0,0 +1,134 @@
<template>
<el-card style="margin-bottom:20px;">
<div slot="header" class="clearfix">
<span>About me</span>
</div>
<div class="user-profile">
<div class="box-center">
<pan-thumb :image="user.avatar" :height="'100px'" :width="'100px'" :hoverable="false">
<div>Hello</div>
{{ user.role }}
</pan-thumb>
</div>
<div class="box-center">
<div class="user-name text-center">{{ user.name }}</div>
<div class="user-role text-center text-muted">{{ user.role | uppercaseFirst }}</div>
</div>
</div>
<div class="user-bio">
<div class="user-education user-bio-section">
<div class="user-bio-section-header"><svg-icon icon-class="education" /><span>Education</span></div>
<div class="user-bio-section-body">
<div class="text-muted">
JS in Computer Science from the University of Technology
</div>
</div>
</div>
<div class="user-skills user-bio-section">
<div class="user-bio-section-header"><svg-icon icon-class="skill" /><span>Skills</span></div>
<div class="user-bio-section-body">
<div class="progress-item">
<span>Vue</span>
<el-progress :percentage="70" />
</div>
<div class="progress-item">
<span>JavaScript</span>
<el-progress :percentage="18" />
</div>
<div class="progress-item">
<span>Css</span>
<el-progress :percentage="12" />
</div>
<div class="progress-item">
<span>ESLint</span>
<el-progress :percentage="100" status="success" />
</div>
</div>
</div>
</div>
</el-card>
</template>
<script>
import PanThumb from '@/components/PanThumb'
export default {
components: { PanThumb },
props: {
user: {
type: Object,
default: () => {
return {
name: '',
email: '',
avatar: '',
roles: ''
}
}
}
}
}
</script>
<style lang="scss" scoped>
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
.user-profile {
.user-name {
font-weight: bold;
}
.box-center {
padding-top: 10px;
}
.user-role {
padding-top: 10px;
font-weight: 400;
font-size: 14px;
}
.box-social {
padding-top: 30px;
.el-table {
border-top: 1px solid #dfe6ec;
}
}
.user-follow {
padding-top: 20px;
}
}
.user-bio {
margin-top: 20px;
color: #606266;
span {
padding-left: 4px;
}
.user-bio-section {
font-size: 14px;
padding: 15px 0;
.user-bio-section-header {
border-bottom: 1px solid #dfe6ec;
padding-bottom: 10px;
margin-bottom: 10px;
font-weight: bold;
}
}
}
</style>

121
src/views/profile/index.vue Normal file
View File

@ -0,0 +1,121 @@
<template>
<BasicLayout>
<template #wrapper>
<el-row :gutter="10">
<el-col :span="6" :xs="24">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div>
<div class="text-center">
<userAvatar :user="user" />
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
<svg-icon icon-class="user" />用户名称
<div class="pull-right">{{ user.username }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ user.phone }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ user.email }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right">{{ deptName }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色
<div class="pull-right">{{ roleName }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ user.createdAt }}</div>
</li>
</ul>
</div>
</el-card>
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<div slot="header" class="clearfix">
<span>基本资料</span>
</div>
<el-tabs v-model="activeTab">
<el-tab-pane label="基本资料" name="userinfo">
<userInfo :user="user" />
</el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd">
<resetPwd :user="user" />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</template>
</BasicLayout>
</template>
<script>
import userAvatar from './userAvatar'
import userInfo from './userInfo'
import resetPwd from './resetPwd'
import { getUserProfile } from '@/api/admin/sys-user'
export default {
name: 'Profile',
components: { userAvatar, userInfo, resetPwd },
data() {
return {
user: {},
roleGroup: {},
postGroup: {},
deptGroup: {},
activeTab: 'userinfo',
roleIds: undefined,
postIds: undefined,
roleName: undefined,
postName: undefined,
dept: {},
deptName: undefined
}
},
created() {
this.getUser()
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data.user
this.roleIds = response.data.user.roleIds
this.roleGroup = response.data.roles
if (this.roleIds[0]) {
for (const key in this.roleGroup) {
if (this.roleIds[0] === this.roleGroup[key].roleId) {
this.roleName = this.roleGroup[key].roleName
}
}
} else {
this.roleName = '暂无'
}
this.dept = response.data.user.dept
this.deptName = this.dept.deptName
})
}
}
}
</script>
<style lang="scss" scoped>
.list-group-item{
padding: 18px 0;
}
.svg-icon{
margin-right: 5px;
}
</style>

View File

@ -0,0 +1,76 @@
<template>
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="user.confirmPassword" placeholder="请确认密码" type="password" />
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserPwd } from '@/api/admin/sys-user'
export default {
data() {
const equalToPassword = (rule, value, callback) => {
if (this.user.newPassword !== value) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
return {
test: '1test',
user: {
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined
},
// 表单校验
rules: {
oldPassword: [
{ required: true, message: '旧密码不能为空', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '新密码不能为空', trigger: 'blur' },
{ min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '确认密码不能为空', trigger: 'blur' },
{ required: true, validator: equalToPassword, trigger: 'blur' }
]
}
}
},
methods: {
submit() {
this.$refs['form'].validate(valid => {
if (valid) {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(
response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
} else {
this.msgError(response.msg)
}
}
)
}
})
},
close() {
this.$store.dispatch('tagsView/delView', this.$route)
this.$router.push({ path: '/index' })
}
}
}
</script>

View File

@ -0,0 +1,137 @@
<template>
<div>
<img :src="options.img" title="点击上传头像" class="img-circle img-lg" @click="editCropper()">
<el-dialog :title="title" :visible.sync="open" width="800px" :close-on-click-modal="false">
<el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<vue-cropper
ref="cropper"
:img="options.img"
:info="true"
:auto-crop="options.autoCrop"
:auto-crop-width="options.autoCropWidth"
:auto-crop-height="options.autoCropHeight"
:fixed-box="options.fixedBox"
@realTime="realTime"
/>
</el-col>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<div class="avatar-upload-preview">
<img :src="previews.url" :style="previews.img">
</div>
</el-col>
</el-row>
<br>
<el-row>
<el-col :lg="2" :md="2">
<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
<el-button size="small">
上传
<i class="el-icon-upload el-icon--right" />
</el-button>
</el-upload>
</el-col>
<el-col :lg="{span: 1, offset: 2}" :md="2">
<el-button icon="el-icon-plus" size="small" @click="changeScale(1)" />
</el-col>
<el-col :lg="{span: 1, offset: 1}" :md="2">
<el-button icon="el-icon-minus" size="small" @click="changeScale(-1)" />
</el-col>
<el-col :lg="{span: 1, offset: 1}" :md="2">
<el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()" />
</el-col>
<el-col :lg="{span: 1, offset: 1}" :md="2">
<el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()" />
</el-col>
<el-col :lg="{span: 2, offset: 6}" :md="2">
<el-button type="primary" size="small" @click="uploadImg()"> </el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import store from '@/store'
import { VueCropper } from 'vue-cropper'
import { uploadAvatar } from '@/api/admin/sys-user'
export default {
components: { VueCropper },
props: {
// eslint-disable-next-line vue/require-default-prop
user: { type: Object }
},
data() {
return {
// 是否显示弹出层
open: false,
// 弹出层标题
title: '修改头像',
options: {
img: store.getters.avatar, // 裁剪图片的地址
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 200, // 默认生成截图框宽度
autoCropHeight: 200, // 默认生成截图框高度
fixedBox: true // 固定截图框大小 不允许改变
},
previews: {}
}
},
methods: {
// 编辑头像
editCropper() {
this.open = true
},
// 覆盖默认的上传行为
requestUpload() {
},
// 向左旋转
rotateLeft() {
this.$refs.cropper.rotateLeft()
},
// 向右旋转
rotateRight() {
this.$refs.cropper.rotateRight()
},
// 图片缩放
changeScale(num) {
num = num || 1
this.$refs.cropper.changeScale(num)
},
// 上传预处理
beforeUpload(file) {
if (file.type.indexOf('image/') === -1) {
this.msgError('文件格式错误,请上传图片类型,如JPGPNG后缀的文件。')
} else {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
this.options.img = reader.result
}
}
},
// 上传图片
uploadImg() {
this.$refs.cropper.getCropBlob(data => {
const formData = new FormData()
formData.append('upload[]', data)
uploadAvatar(formData).then(response => {
if (response.code === 200) {
this.open = false
this.options.img = process.env.VUE_APP_BASE_API + response.data
this.msgSuccess(response.msg)
} else {
this.msgError(response.msg)
}
this.$refs.cropper.clearCrop()
})
})
},
// 实时预览
realTime(data) {
this.previews = data
}
}
}
</script>

View File

@ -0,0 +1,79 @@
<template>
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="user.nickName" />
</el-form-item>
<el-form-item label="手机号码" prop="phone">
<el-input v-model="user.phone" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="user.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="user.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUser } from '@/api/admin/sys-user'
export default {
props: {
// eslint-disable-next-line vue/require-default-prop
user: { type: Object }
},
data() {
return {
// 表单校验
rules: {
nickName: [
{ required: true, message: '用户昵称不能为空', trigger: 'blur' }
],
email: [
{ required: true, message: '邮箱地址不能为空', trigger: 'blur' },
{
type: 'email',
message: "'请输入正确的邮箱地址",
trigger: ['blur', 'change']
}
],
phone: [
{ required: true, message: '手机号码不能为空', trigger: 'blur' },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur'
}
]
}
}
},
methods: {
submit() {
this.$refs['form'].validate(valid => {
if (valid) {
updateUser(this.user).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
} else {
this.msgError(response.msg)
}
})
}
})
},
close() {
this.$store.dispatch('tagsView/delView', this.$route)
this.$router.push({ path: '/index' })
}
}
}
</script>

View File

@ -0,0 +1,12 @@
<script>
export default {
created() {
const { params, query } = this.$route
const { path } = params
this.$router.replace({ path: '/' + path, query })
},
render: function(h) {
return h() // avoid warning message
}
}
</script>

View File

@ -0,0 +1,558 @@
<template>
<div>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-position="left" label-width="68px">
<el-form-item label="名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务分组" prop="jobGroup">
<el-select
v-model="queryParams.jobGroup"
placeholder="定时任务任务分组"
clearable
size="small"
>
<el-option
v-for="dict in jobGroupOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="定时任务状态"
clearable
size="small"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-permisaction="['job:sysJob:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['job:sysJob:edit']"
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['job:sysJob:remove']"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-permisaction="['job:sysJob:log']"
type="danger"
icon="el-icon-delete"
size="mini"
@click="handleLog"
>日志
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="sysjobList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="编码"
align="center"
prop="jobId"
:show-overflow-tooltip="true"
/>
<el-table-column
label="名称"
align="center"
prop="jobName"
:show-overflow-tooltip="true"
/>
<el-table-column
label="任务分组"
align="center"
prop="jobGroup"
:formatter="jobGroupFormat"
width="100"
>
<template slot-scope="scope">
{{ jobGroupFormat(scope.row) }}
</template>
</el-table-column>
<el-table-column
label="cron表达式"
align="center"
prop="cronExpression"
:show-overflow-tooltip="true"
/>
<el-table-column
label="调用目标"
align="center"
prop="invokeTarget"
:show-overflow-tooltip="true"
/>
<el-table-column
label="状态"
align="center"
prop="status"
:formatter="statusFormat"
width="100"
>
<template slot-scope="scope">
{{ statusFormat(scope.row) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-permisaction="['job:sysJob:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改
</el-button>
<el-button
v-if="scope.row.entry_id!==0&& scope.row.status!=1"
v-permisaction="['job:sysJob:remove']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleRemove(scope.row)"
>停止
</el-button>
<el-button
v-if="scope.row.entry_id==0 && scope.row.status!=1"
v-permisaction="['job:sysJob:start']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleStart(scope.row)"
>启动
</el-button>
<el-button
v-permisaction="['job:sysJob:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageIndex"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog v-dialogDrag :title="title" :visible.sync="open" width="700px" append-to-body :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="名称" prop="jobName">
<el-input
v-model="form.jobName"
placeholder="名称"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组" prop="jobGroup">
<el-select
v-model="form.jobGroup"
placeholder="请选择"
>
<el-option
v-for="dict in jobGroupOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用目标" prop="invokeTarget">
<span slot="label">
调用目标
<el-tooltip placement="top">
<div slot="content">
调用示例func (t *EXEC) ExamplesNoParam(){..} 填写 ExamplesNoParam 即可
<br>参数说明目前不支持带参调用
</div>
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input
v-model="form.invokeTarget"
placeholder="调用目标"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="目标参数" prop="args">
<span slot="label">
目标参数
<el-tooltip placement="top">
<div slot="content">
参数示例有参请以string格式填写无参为空
<br>参数说明目前仅支持函数调用
</div>
<i class="el-icon-question" />
</el-tooltip>
</span>
<el-input
v-model="form.args"
placeholder="目标参数"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="cron表达式" prop="cronExpression">
<el-input
v-model="form.cronExpression"
placeholder="cron表达式"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否并发" prop="concurrent">
<el-radio-group v-model="form.concurrent" size="small">
<el-radio-button label="0">允许</el-radio-button>
<el-radio-button label="1">禁止</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用类型" prop="jobType">
<el-radio-group v-model="form.jobType" size="small">
<el-radio-button label="1">接口</el-radio-button>
<el-radio-button label="2">函数</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="执行策略" prop="misfirePolicy">
<el-radio-group v-model="form.misfirePolicy" size="small">
<el-radio-button label="1">立即执行</el-radio-button>
<el-radio-button label="2">执行一次</el-radio-button>
<el-radio-button label="3">放弃执行</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="status">
<el-select
v-model="form.status"
placeholder="请选择"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card>
</template>
</BasicLayout>
</div>
</template>
<script>
import { addSysJob, delSysJob, getSysJob, listSysJob, updateSysJob, removeJob, startJob } from '@/api/job/sys-job'
export default {
name: 'SysJobManage',
components: {
},
data() {
return {
// 遮罩层
loading: true,
id: 0,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
isEdit: false,
// 类型数据字典
typeOptions: [],
sysjobList: [],
jobGroupOptions: [],
statusOptions: [],
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
},
// 表单参数
form: {
},
// 表单校验
rules: {
jobId: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
jobName: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
jobGroup: [{ required: true, message: '任务分组不能为空', trigger: 'blur' }],
cronExpression: [{ required: true, message: 'cron表达式不能为空', trigger: 'blur' }],
invokeTarget: [{ required: true, message: '调用目标不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getList()
this.getDicts('sys_job_group').then(response => {
this.jobGroupOptions = response.data
})
this.getDicts('sys_job_status').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listSysJob(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.sysjobList = response.data.list
this.total = response.data.count
this.loading = false
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
jobId: undefined,
jobName: undefined,
jobGroup: undefined,
cronExpression: undefined,
invokeTarget: undefined,
args: undefined,
misfirePolicy: 1,
concurrent: 1,
jobType: 1,
status: undefined
}
this.resetForm('form')
},
jobGroupFormat(row) {
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup)
},
statusFormat(row) {
return this.selectDictLabel(this.statusOptions, row.status)
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageIndex = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加定时任务'
this.isEdit = false
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const jobId = row.jobId || this.ids
getSysJob(jobId).then(response => {
this.form = response.data
this.form.status = String(this.form.status)
this.form.misfirePolicy = String(this.form.misfirePolicy)
this.form.concurrent = String(this.form.concurrent)
this.form.jobType = String(this.form.jobType)
this.open = true
this.title = '修改定时任务'
this.isEdit = true
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.jobId !== undefined) {
this.form.status = parseInt(this.form.status)
this.form.misfirePolicy = parseInt(this.form.misfirePolicy)
this.form.concurrent = parseInt(this.form.concurrent)
this.form.jobType = parseInt(this.form.jobType)
updateSysJob(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
this.form.status = parseInt(this.form.status)
this.form.misfirePolicy = parseInt(this.form.misfirePolicy)
this.form.concurrent = parseInt(this.form.concurrent)
this.form.jobType = parseInt(this.form.jobType)
addSysJob(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const Ids = (row.jobId && [row.jobId]) || this.ids
this.$confirm('是否确认删除编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delSysJob({ 'ids': Ids })
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 开始按钮操作 */
handleStart(row) {
this.$confirm('是否确认启动编号为"' + row.jobId + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return startJob(row.jobId)
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
/** 停止按钮操作 */
handleRemove(row) {
this.$confirm('是否确认关闭编号为"' + row.jobId + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return removeJob(row.jobId)
}).then((response) => {
if (response.code === 200) {
this.msgSuccess(response.msg)
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
}).catch(function() {})
},
handleLog() {
this.$router.push({ name: 'job_log', params: { }})
}
}
}
</script>

101
src/views/schedule/log.vue Normal file
View File

@ -0,0 +1,101 @@
<template>
<BasicLayout>
<template #wrapper>
<el-card class="box-card">
<el-form>
<el-form-item>
<el-button type="success" icon="el-icon-search" size="mini">状态</el-button>
<el-button type="primary" icon="el-icon-search" size="mini">清空</el-button>
</el-form-item>
</el-form>
<el-row ref="log" :gutter="10" class="mb8">
<el-scrollbar style="height:500px;background-color: black;color: cornflowerblue;">
<ul
style="line-height: 25px;padding-top: 15px;padding-bottom: 15px;min-height: 500px; margin: 0;list-style-type: none;"
>
<li v-for="(item,index) in arrs" :key="index">
{{ item }}
</li>
</ul>
</el-scrollbar>
</el-row>
</el-card>
</template>
</BasicLayout>
</template>
<script>
import { unWsLogout } from '@/api/ws'
export default {
name: 'SysJobLogManage',
data() {
return {
websock: null,
arrs: [],
id: undefined,
group: undefined
}
},
created() {
this.id = this.guid()
this.group = 'log'
this.initWebSocket()
},
destroyed() {
console.log('断开websocket连接')
this.websock.close() // 离开路由之后断开websocket连接
unWsLogout(this.id, this.group).then(response => {
console.log(response.data)
}
)
},
methods: {
initWebSocket() { // 初始化weosocket
console.log(this.$store.state.user.token)
const wsuri = 'ws://127.0.0.1:8000/ws/' + this.id + '/' + this.group + '?token=' + this.$store.state.user.token
this.websock = new WebSocket(wsuri)
this.websock.onmessage = this.websocketonmessage
this.websock.onopen = this.websocketonopen
this.websock.onerror = this.websocketonerror
this.websock.onclose = this.websocketclose
},
websocketonopen() { // 连接建立之后执行send方法发送数据
console.log('连接打开')
// const actions = { 'test': '12345' }
// this.websocketsend(JSON.stringify(actions))
},
websocketonerror() { // 连接建立失败重连
this.initWebSocket()
},
websocketonmessage(e) { // 数据接收
console.log(e.data)
// console.log(this.binaryAgent(e))
// const redata = JSON.parse(e.data)
// console.log(redata)
// this.$refs.log.innerText = e.data + '\n' + this.$refs.log.innerText
this.arrs.unshift(e.data)
},
websocketsend(Data) { // 数据发送
// this.websock.send(Data)
},
websocketclose(e) { // 关闭
unWsLogout(this.id, this.group).then(response => {
console.log(response.data)
}
)
console.log('断开连接', e)
},
guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0; var v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
}
}
</script>

View File

@ -0,0 +1,193 @@
<template>
<div>
<BasicLayout>
<template #wrapper>
<el-row :gutter="10" class="mb10">
<el-col :sm="24" :md="8">
<el-card v-if="info.cpu" class="box-card" shadow="always" :body-style="{paddingTop:'0 !important'}">
<div slot="header" class="clearfix">
<el-row :gutter="10">
<el-col :sm="24" :md="8">
<el-tag
type="success"
effect="dark"
>
Runing
</el-tag>
</el-col>
<el-col :sm="24" :md="8" class="" style="line-height:28px;text-align:center;">
{{ info.location }}
</el-col>
</el-row>
</div>
<div class="monitor" style="padding-top:0px;">
<div class="monitor-content">
<el-row :gutter="10">
<el-col :sm="24" :md="12">
<Cell label="系统" :value="info.os.goOs" border />
<Cell label="内存" :value="`${info.mem.used}MB/${info.mem.total}MB`" border />
<Cell label="交换" :value="`${info.swap.used}/${info.swap.total}`" border />
</el-col>
<el-col :sm="24" :md="12">
<Cell label="时间" :value="info.os.time" border />
<Cell label="在线" :value="`${info.bootTime}小时`" border />
<Cell label="硬盘" :value="`${info.disk.used}GB/${info.disk.total}GB`" border />
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :sm="12" :md="12" class="line">
<el-row>
<el-col span="12" :sm="8" :md="8" xs="12">
下载<i class="el-icon-caret-bottom" />
</el-col>
<el-col span="12" :sm="16" :md="16" xs="12" class="line-value">
{{ info.net.in }}KB
</el-col>
</el-row>
</el-col>
<el-col :sm="12" :md="12" class="line">
<el-row border>
<el-col span="12" :sm="6" :md="8">
上传<i class="el-icon-caret-top" />
</el-col>
<el-col span="12" :sm="6" :md="16" class="line-value">
{{ info.net.out }}KB
</el-col>
</el-row>
</el-col>
</el-row>
<el-row :gutter="10" class="monitor-progress">
<el-col :sm="24" :md="4">
CPU
</el-col>
<el-col :sm="24" :md="20">
<el-progress :color="customColors" :text-inside="true" :stroke-width="24" :percentage="info.cpu.percent" />
</el-col>
</el-row>
<el-row :gutter="10" class="monitor-progress">
<el-col :sm="24" :md="4">
RAM
</el-col>
<el-col :sm="24" :md="20">
<el-progress :color="customColors" :text-inside="true" :stroke-width="24" :percentage="info.mem.percent" />
</el-col>
</el-row>
<el-row :gutter="10" class="monitor-progress">
<el-col :sm="24" :md="4">
硬盘
</el-col>
<el-col :sm="24" :md="20">
<el-progress :color="customColors" :text-inside="true" :stroke-width="24" :percentage="info.disk.percent" />
</el-col>
</el-row>
<!-- <el-progress :color="$store.state.settings.theme" type="circle" :percentage="info.cpu.Percent" /> -->
</div>
<!-- <div class="monitor-footer">
<Cell label="CPU主频" :value="info.cpu.cpuInfo[0].modelName.split('@ ')[1]" border />
<Cell label="核心数" :value="`${info.cpu.cpuInfo[0].cores}`" />
</div> -->
</div>
</el-card>
</el-col>
<!-- <el-card v-if="info.os" class="box-card">
<div slot="header" class="clearfix">
<span>go运行环境</span>
</div>
<div class="monitor">
<Cell label="GO 版本" :value="info.os.version" border />
<Cell label="Goroutine" :value="`${info.os.numGoroutine}`" border />
<Cell label="项目地址" :value="info.os.projectDir" />
</div>
</el-card> -->
<el-card v-if="info.os" class="box-card">
<div slot="header" class="clearfix">
<span>服务器信息</span>
</div>
<div class="monitor">
<Cell label="主机名称" :value="info.os.hostName" border />
<Cell label="操作系统" :value="info.os.goOs" border />
<Cell label="服务器IP" :value="info.os.ip" border />
<Cell label="系统架构" :value="info.os.arch" border />
<Cell label="CPU" :value="info.cpu.cpuInfo[0].modelName" border />
<Cell label="当前时间" :value="info.os.time" />
</div>
</el-card>
</el-row></template>
</BasicLayout>
</div>
</template>
<script>
import Cell from '@/components/Cell/index'
import {
getServer
} from '@/api/monitor/server'
export default {
name: 'Monitor',
components: {
Cell
},
data() {
return {
info: {},
customColors: [
{ color: '#13ce66', percentage: 20 },
{ color: '#1890ff', percentage: 40 },
{ color: '#e6a23c', percentage: 60 },
{ color: '#1989fa', percentage: 80 },
{ color: '#F56C6C', percentage: 100 }
],
timer: null
}
},
created() {
this.getServerInfo()
this.timer = setInterval(() => {
this.getServerInfo()
}, 1000)
},
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
},
methods: {
getServerInfo() {
getServer().then(ret => {
if (ret.code === 200) {
this.info = ret
}
})
}
}
}
</script>
<style lang="scss" scoped>
.line{
line-height: 49px;
font-size: 14px ;
padding-left: 5px !important;
padding-right: 5px !important;
border-bottom: 1px solid #e6ebf5;
.line-value{
text-align: right;
color: #969799;
}
}
.monitor {
.monitor-header {
display: flex;
justify-content: center;
align-items: center;
}
.monitor-progress{
padding-top: 15px;
}
}
</style>