y1111 #7
127
src/components/ApiFormModal.vue
Normal file
127
src/components/ApiFormModal.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div v-if="visible" class="modal fade show" id="exampleModalCenter" tabindex="-1" aria-labelledby="exampleModalLabel" style="display: block; padding-right: 15px;" _mstvisible="0" aria-modal="true" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" _mstvisible="1">
|
||||
<div class="modal-content" _mstvisible="2">
|
||||
<div class="modal-header" _mstvisible="3">
|
||||
<h5 class="modal-title" id="exampleModalCenterTitle" _msttexthash="13222534" _msthash="147" _mstvisible="4">{{title}}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭" _mstaria-label="59709" _msthash="148" _mstvisible="4" @click="cancel"></button>
|
||||
</div>
|
||||
<div class="formcontent">
|
||||
<form>
|
||||
<div class="row mb-3">
|
||||
<label for="inputName3" class="col-sm-2 col-form-label">接口名称</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" v-model="form.name" class="form-control" id="inputName3">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputDescription3" class="col-sm-2 col-form-label">接口描述</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" v-model="form.description" class="form-control" id="inputDescription3">
|
||||
</div>
|
||||
</div>
|
||||
<fieldset class="row mb-3">
|
||||
<legend class="col-form-label col-sm-2 pt-0">调用方法</legend>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" v-model="form.method" value="0" :checked="form.method == 0 ? true : false">
|
||||
<label class="form-check-label" for="gridRadios1">
|
||||
GET
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" v-model="form.method" value="1" :checked="form.method == 1 ? true : false">
|
||||
<label class="form-check-label" for="gridRadios1">
|
||||
POST
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="row mb-3">
|
||||
<label class="visually-hidden" for="PackageSelect">所属套餐</label>
|
||||
<select class="form-select" id="PackageSelect" v-model="form.packageId">
|
||||
<option v-for="(item,index) in packageList" :key="index" :value="item.id" :selected="form.packageId == item.id ? true : false">{{item.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer" _mstvisible="3">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" _msttexthash="5889065" _msthash="150" _mstvisible="4" @click="cancel">关闭</button>
|
||||
<button type="button" class="btn btn-primary" _msttexthash="10744773" _msthash="151" _mstvisible="4" @click="submit">保存更改</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'ApiFormModal',
|
||||
props:{
|
||||
title:{
|
||||
type:String
|
||||
},
|
||||
formType: {
|
||||
type: String,
|
||||
default: 'edit'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
ApiId: -2,
|
||||
packageList: [],
|
||||
form: {
|
||||
name: '',
|
||||
description: '',
|
||||
method: '0',
|
||||
packageId: '0'
|
||||
},
|
||||
resolve: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
open(apiId,apiInfo = null,packageList) {
|
||||
this.resetForm();
|
||||
this.visible = true;
|
||||
this.apiId = apiId;
|
||||
this.form.name = apiInfo.name;
|
||||
this.form.description = apiInfo.description;
|
||||
this.form.method = apiInfo.method.toString();
|
||||
this.form.packageId = apiInfo.packageId.toString();
|
||||
this.packageList = packageList
|
||||
return new Promise((resolve) => {
|
||||
this.resolve = resolve;
|
||||
});
|
||||
},
|
||||
submit() {
|
||||
this.visible = false;
|
||||
this.form.method = Number(this.form.method)
|
||||
this.form.packageId = Number(this.form.packageId)
|
||||
this.resolve && this.resolve(this.form);
|
||||
},
|
||||
cancel() {
|
||||
this.visible = false;
|
||||
this.resolve && this.resolve(null);
|
||||
},
|
||||
resetForm() {
|
||||
this.form = {
|
||||
name: '',
|
||||
description: '',
|
||||
method: '0',
|
||||
packageId: '0'
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.modal {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.formcontent {
|
||||
padding: 0 30px;
|
||||
}
|
||||
</style>
|
||||
@ -109,6 +109,20 @@
|
||||
<div v-if="header.type == 'datetime'">
|
||||
<span>{{ formatDateTime(item[header.value]) }}</span>
|
||||
</div>
|
||||
<div v-if="header.type == 'method'">
|
||||
<span
|
||||
:class="[
|
||||
'badge',
|
||||
'bg-warning',
|
||||
]"
|
||||
>{{ callMethod[item[header.value]] }}</span
|
||||
>
|
||||
</div>
|
||||
<div v-if="header.type == 'find'">
|
||||
<span class="badge bg-info">
|
||||
{{ header.findValue.find(x => x.id == item[header.value]).name }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
@ -259,6 +273,8 @@ export default {
|
||||
pageCount: 0,
|
||||
//分页按钮数据,[{text:'1',index:1},.....]
|
||||
pageBtn: [],
|
||||
//调用方法
|
||||
callMethod:['GET','POST']
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
|
||||
@ -42,6 +42,21 @@ const deletePackage = async (id) => await request.delete(`/api/Package/DeletePac
|
||||
const updatePackage = async (id, param) => await request.post(`/api/Package/UpdatePackage?packageId=${id}`, param)
|
||||
|
||||
const addPackage = async (param) => await request.post('/api/Package/AddPackage', param)
|
||||
//获取api列表
|
||||
const getApiList = async (pageIndex,pageSize,desc) => await request.get(`/api/apis/ApiList?pageIndex=${pageIndex}&pageSize=${pageSize}&desc=${desc}`)
|
||||
|
||||
//删除API
|
||||
const deleteApi = async (id) => await request.delete(`/api/Apis/DeleteApi?apiId=${id}`)
|
||||
|
||||
//获取指定API信息
|
||||
const getApiInfoById = async (id) => await request.get(`/api/Apis/ApiInfo?apiId=${id}`)
|
||||
|
||||
//更新API信息
|
||||
const updateApiInfo = async (id,param) => await request.post(`/api/Apis/UpdateApi?apiId=${id}`,param)
|
||||
|
||||
//更新系统配置
|
||||
const updateSystemConfig = async (configName,configBody) => await request.post('/api/SystemConfig/UpdateSystemConfig',{configName:configName,configBody:configBody})
|
||||
|
||||
export default {
|
||||
login,
|
||||
register,
|
||||
@ -57,5 +72,11 @@ export default {
|
||||
getPackageInfo,
|
||||
deletePackage,
|
||||
updatePackage,
|
||||
addPackage
|
||||
addPackage,
|
||||
deleteApi,
|
||||
getApiInfoById,
|
||||
updateApiInfo,
|
||||
getPackageList,
|
||||
updateSystemConfig,
|
||||
getApiList
|
||||
}
|
||||
@ -6,7 +6,11 @@
|
||||
<DataTable title="API管理"
|
||||
:headers="tableHeaders"
|
||||
:rows="tableData"
|
||||
:data-count="dataCount" />
|
||||
:data-count="dataCount"
|
||||
@pageChanged="pageChangedHandle"
|
||||
@dataDelete="deleteHandle"
|
||||
@dataModify="modifyHandle" />
|
||||
<api-form-modal title="修改接口" ref="apiModal" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -14,27 +18,104 @@
|
||||
|
||||
<script>
|
||||
import DataTable from '@/components/DataTable.vue';
|
||||
import ApiFormModal from '../../components/ApiFormModal.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: "APIs",
|
||||
components: {
|
||||
DataTable
|
||||
DataTable,
|
||||
ApiFormModal
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoaded: false,
|
||||
packageList: [],
|
||||
tableHeaders: [
|
||||
{ text: "", value: "", width: "" }
|
||||
{ text: "编号", value: "id", width: "100px" },
|
||||
{ text: "名称", value: "name", width: "100px" },
|
||||
{ text: "描述", value: "description", width: "100px" },
|
||||
{ text: "路径", value: "endpoint", width: "100px" },
|
||||
{ text: "调用方法", value: "method", width: "100px", type: "method" },
|
||||
{ text: "状态", value: "isactive", width: "100px", type: "bool" },
|
||||
{ text: "所属套餐", value: "packageId", width: "100px", type: "find", findProperty: "id", findValue: [] },
|
||||
],
|
||||
tableData: [],
|
||||
dataCount: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadApiList(pageIndex = 1, pageSize = 10, desc = false) {
|
||||
try {
|
||||
const res = await this.$api.getApiList(pageIndex, pageSize, desc)
|
||||
if (res.code == '1000') {
|
||||
this.tableData = res.data
|
||||
}
|
||||
} catch (e) {
|
||||
this.$alert('API列表数据加载失败!', 'danger')
|
||||
console.error(e)
|
||||
}
|
||||
},
|
||||
async pageChangedHandle(newval) {
|
||||
await this.loadApiList(newval.pageIndex, newval.pageSize, false)
|
||||
},
|
||||
async modifyHandle(id) {
|
||||
try {
|
||||
//加载API信息到新窗口
|
||||
const apiinfoRes = await this.$api.getApiInfoById(id)
|
||||
if (apiinfoRes.code != 1000) {
|
||||
this.$alert(apiinfoRes.message, 'danger')
|
||||
return
|
||||
}
|
||||
|
||||
//拉起修改弹窗
|
||||
const res = await this.$refs.apiModal.open(id, apiinfoRes.data, this.packageList)
|
||||
//弹窗返回为null表示用户关闭了窗口,不执行操作
|
||||
if (res == null) return
|
||||
const modifyRes = await this.$api.updateApiInfo(id, res)
|
||||
if (modifyRes.code != 1000) {
|
||||
this.$alert(modifyRes.message, 'danger')
|
||||
return
|
||||
}
|
||||
this.$alert('修改成功', 'success')
|
||||
|
||||
} catch (e) {
|
||||
this.$alert(e, 'danger')
|
||||
}
|
||||
},
|
||||
async deleteHandle(id) {
|
||||
const confirmRes = await this.$confirm('删除', '是否删除API?')
|
||||
if (!confirmRes) return;
|
||||
try {
|
||||
const res = await this.$api.deleteApi(id)
|
||||
if (res.code != 1000) {
|
||||
this.$alert(res.message, 'danger')
|
||||
return;
|
||||
}
|
||||
this.$alert('删除成功', 'success')
|
||||
|
||||
} catch (e) {
|
||||
this.$alert(e, 'danger')
|
||||
}
|
||||
},
|
||||
async loadPackageList(pageIndex = 1, pageSize = 10, desc = false) {
|
||||
//获取套餐列表
|
||||
try{
|
||||
const packageRes = await this.$api.getPackageList(1, 1000, false)
|
||||
if (packageRes.code != 1000) {
|
||||
this.$alert(packageRes.message, 'danger')
|
||||
}
|
||||
this.packageList = packageRes.data
|
||||
}catch(e){
|
||||
this.$alert('加载套餐列表失败!', 'danger')
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
async mounted() {
|
||||
await this.loadApiList()
|
||||
await this.loadPackageList()
|
||||
this.tableHeaders.find(x => x.value == 'packageId').findValue = this.packageList
|
||||
this.isLoaded = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="row justify-content-center mt-5">
|
||||
<div class="main-wrapper">
|
||||
<div class="row justify-content-center">
|
||||
<div class="card custom-card">
|
||||
<div class="card-header text-center">
|
||||
<h3 class="card-title">充值中心</h3>
|
||||
@ -75,6 +76,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
<template>
|
||||
|
||||
<div class="main-wrapper">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col m-b-sm" v-for="(item,index) in packageList" :key="index">
|
||||
<ul class="list-group io-pricing-table">
|
||||
<li class="list-group-item">
|
||||
<h3>{{ item.name }}</h3>
|
||||
</li>
|
||||
<li class="list-group-item">每分钟调用次数限制:{{ item.oneMinuteLimit }} 次</li>
|
||||
<li class="list-group-item">周期总调用次数:{{ item.callLimit }} 次</li>
|
||||
<li class="list-group-item">
|
||||
<h3>¥{{ item.price }}</h3>
|
||||
<span>每月</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<button type="button" class="btn btn-primary">购买</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name:'BuyPackage',
|
||||
data(){
|
||||
return {
|
||||
packageList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//加载套餐列表
|
||||
async loadPackageList(){
|
||||
try{
|
||||
const res = await this.$api.getPackageList(1,100,false)
|
||||
if(res.code != 1000){
|
||||
this.$alert(res.message,'danger')
|
||||
return
|
||||
}
|
||||
this.packageList = res.data
|
||||
return
|
||||
}catch(e){
|
||||
this.$alert('加载套餐列表失败!','danger')
|
||||
console.error('套餐列表加载失败:',e)
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted(){
|
||||
await this.loadPackageList()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<div class="main-wrapper">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card shadow-sm border-0 mt-4">
|
||||
<div class="card-header bg-gradient text-white py-4">
|
||||
<h4 class="mb-0">个人中心</h4>
|
||||
<p class="mb-0 small">管理您的账户信息与安全设置</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<!-- 用户头像 -->
|
||||
<div class="text-center mb-4">
|
||||
<img :src="user.avatar" class="rounded-circle border" width="100" height="100" />
|
||||
<div class="mt-2">
|
||||
<button class="btn btn-outline-primary btn-sm" @click="editingSection = 'avatar'">修改头像</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户信息列表 -->
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><strong>昵称:</strong>{{ user.nickname }}</span>
|
||||
<button class="btn btn-link" @click="openEdit('nickname')">修改</button>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><strong>邮箱:</strong>{{ user.email }}</span>
|
||||
<button class="btn btn-link" @click="openEdit('email')">修改</button>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><strong>手机号:</strong>{{ user.phone }}</span>
|
||||
<button class="btn btn-link" @click="openEdit('phone')">修改</button>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><strong>性别:</strong>{{ getGenderLabel(user.gender) }}</span>
|
||||
<button class="btn btn-link" @click="openEdit('gender')">修改</button>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><strong>个人简介:</strong>{{ user.bio || '未填写' }}</span>
|
||||
<button class="btn btn-link" @click="openEdit('bio')">修改</button>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><strong>登录密码:</strong>********</span>
|
||||
<button class="btn btn-link" @click="openEdit('password')">修改</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 弹出框 -->
|
||||
<div v-if="editingSection" class="modal fade show d-block" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">修改 {{ getSectionTitle(editingSection) }}</h5>
|
||||
<button type="button" class="btn-close" @click="closeEdit"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- 各字段弹出表单内容 -->
|
||||
<div v-if="editingSection === 'nickname'">
|
||||
<input type="text" class="form-control" v-model="form.nickname" placeholder="请输入昵称" />
|
||||
</div>
|
||||
<div v-else-if="editingSection === 'email'">
|
||||
<input type="email" class="form-control" v-model="form.email" placeholder="请输入邮箱" />
|
||||
</div>
|
||||
<div v-else-if="editingSection === 'phone'">
|
||||
<input type="text" class="form-control" v-model="form.phone" placeholder="请输入手机号" />
|
||||
</div>
|
||||
<div v-else-if="editingSection === 'gender'">
|
||||
<select class="form-control" v-model="form.gender">
|
||||
<option value="male">男</option>
|
||||
<option value="female">女</option>
|
||||
<option value="other">其他</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-else-if="editingSection === 'bio'">
|
||||
<textarea class="form-control" rows="3" v-model="form.bio" placeholder="简单介绍一下你自己"></textarea>
|
||||
</div>
|
||||
<div v-else-if="editingSection === 'password'">
|
||||
<input type="password" class="form-control mb-2" v-model="form.oldPassword" placeholder="当前密码" />
|
||||
<input type="password" class="form-control mb-2" v-model="form.newPassword" placeholder="新密码" />
|
||||
<input type="password" class="form-control" v-model="form.confirmPassword" placeholder="确认新密码" />
|
||||
<div class="text-danger mt-1" v-if="form.newPassword !== form.confirmPassword">两次密码不一致</div>
|
||||
</div>
|
||||
<div v-else-if="editingSection === 'avatar'">
|
||||
<input type="file" class="form-control" @change="onAvatarChange" accept="image/*" />
|
||||
<img :src="previewAvatar" class="mt-3 rounded-circle" width="80" v-if="previewAvatar" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" @click="closeEdit">取消</button>
|
||||
<button class="btn btn-primary" @click="saveEdit">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "UserProfilePanel",
|
||||
data() {
|
||||
return {
|
||||
user: {
|
||||
avatar: "https://via.placeholder.com/100",
|
||||
nickname: "张三",
|
||||
email: "zhangsan@example.com",
|
||||
phone: "13800000000",
|
||||
gender: "male",
|
||||
bio: "热爱开源,热爱技术"
|
||||
},
|
||||
editingSection: null,
|
||||
form: {},
|
||||
previewAvatar: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openEdit(section) {
|
||||
this.editingSection = section;
|
||||
this.form = { ...this.user }; // clone
|
||||
},
|
||||
closeEdit() {
|
||||
this.editingSection = null;
|
||||
this.previewAvatar = null;
|
||||
},
|
||||
saveEdit() {
|
||||
if (this.editingSection === 'password') {
|
||||
if (this.form.newPassword !== this.form.confirmPassword) {
|
||||
return;
|
||||
}
|
||||
// 处理密码更新逻辑
|
||||
this.$alert && this.$alert("密码已修改", "success");
|
||||
} else if (this.editingSection === 'avatar') {
|
||||
if (this.previewAvatar) {
|
||||
this.user.avatar = this.previewAvatar;
|
||||
}
|
||||
} else {
|
||||
Object.assign(this.user, this.form);
|
||||
}
|
||||
|
||||
this.closeEdit();
|
||||
},
|
||||
getGenderLabel(value) {
|
||||
return value === 'male' ? '男' : value === 'female' ? '女' : '其他';
|
||||
},
|
||||
getSectionTitle(section) {
|
||||
const map = {
|
||||
nickname: "昵称",
|
||||
email: "邮箱",
|
||||
phone: "手机号",
|
||||
gender: "性别",
|
||||
bio: "个人简介",
|
||||
password: "密码",
|
||||
avatar: "头像"
|
||||
};
|
||||
return map[section] || "信息";
|
||||
},
|
||||
onAvatarChange(e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
this.previewAvatar = event.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bg-gradient {
|
||||
background: linear-gradient(to right, #4e73df, #1cc88a);
|
||||
}
|
||||
.modal {
|
||||
z-index: 1050;
|
||||
}
|
||||
.btn-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div class="main-wrapper">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">系统设置</h5>
|
||||
<p class="card-description">在此页面中配置系统的基本参数。</p>
|
||||
|
||||
<form>
|
||||
<!-- 系统名称 -->
|
||||
<div class="mb-3">
|
||||
<label for="systemName" class="form-label">系统名称</label>
|
||||
<input type="text" class="form-control" id="systemName" v-model="systemName"
|
||||
placeholder="请输入系统名称">
|
||||
</div>
|
||||
|
||||
<!-- 管理员邮箱 -->
|
||||
<div class="mb-3">
|
||||
<label for="adminEmail" class="form-label">管理员邮箱</label>
|
||||
<input type="email" v-model="systemEmail" class="form-control" id="adminEmail"
|
||||
aria-describedby="emailHelp" placeholder="admin@example.com">
|
||||
<div id="emailHelp" class="form-text">我们将在网站显示此邮箱。</div>
|
||||
</div>
|
||||
<!-- 管理员手机号 -->
|
||||
<div class="mb-3">
|
||||
<label for="adminPhone" class="form-label">管理员手机号</label>
|
||||
<input type="text" v-model="systemPhone" class="form-control" id="adminPhone"
|
||||
aria-describedby="PhoneHelp" placeholder="13800000000">
|
||||
<div id="PhoneHelp" class="form-text">我们将在网站显示此邮箱。</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统描述 -->
|
||||
<div class="mb-3">
|
||||
<label for="adminDescription" class="form-label">系统描述</label>
|
||||
<textarea class="form-control" v-model="systemDescription"
|
||||
aria-label="With textarea"></textarea>
|
||||
</div>
|
||||
<!--网站LOGO-->
|
||||
<div class="mb-3">
|
||||
<label for="formFile" class="form-label">网站LOGO</label>
|
||||
<input class="form-control" type="file" id="formFile" accept="image/*">
|
||||
</div>
|
||||
<!--网站Favorite-->
|
||||
<div class="mb-3">
|
||||
<label for="formFile" class="form-label">网站Favorite</label>
|
||||
<input class="form-control" type="file" id="formFile" accept="image/*">
|
||||
</div>
|
||||
<!-- 启用用户注册 -->
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" v-model="enableSystemRegister" class="form-check-input" id="enableRegistration">
|
||||
<label class="form-check-label" for="enableRegistration">启用用户注册功能</label>
|
||||
</div>
|
||||
<!-- 启用注册邮箱验证 -->
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" v-model="enableSystemRegisterEmailValidate" class="form-check-input" id="enableRegistrationValidate">
|
||||
<label class="form-check-label" for="enableRegistrationValidate">启用用户注册邮箱验证</label>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<button type="button" class="btn btn-primary" @click="submit">保存设置</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SystemConfig",
|
||||
data() {
|
||||
return {
|
||||
systemConfig: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
for (const item of this.systemConfig) {
|
||||
const configName = item.configName
|
||||
const configBody = item.configBody
|
||||
try {
|
||||
const res = await this.$api.updateSystemConfig(configName, configBody)
|
||||
if(res.code != 1000) this.$alert(res.message,'danger')
|
||||
} catch (err) {
|
||||
this.$alert('更新配置失败','danger')
|
||||
console.error(`更新 ${configName} 失败`, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 全部成功后提示
|
||||
this.$alert('系统配置已保存','success')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
systemName: {
|
||||
get() {
|
||||
const systemName = this.systemConfig.find(x => x.configName == 'SystemName')
|
||||
return systemName ? systemName.configBody : ''
|
||||
},
|
||||
set(newValue) {
|
||||
const systemName = this.systemConfig.find(x => x.configName == 'SystemName')
|
||||
if (systemName) {
|
||||
systemName.configBody = newValue
|
||||
}
|
||||
}
|
||||
},
|
||||
systemEmail: {
|
||||
get() {
|
||||
const item = this.systemConfig.find(x => x.configName == 'Email')
|
||||
return item ? item.configBody : ''
|
||||
},
|
||||
set(newValue) {
|
||||
const item = this.systemConfig.find(x => x.configName == 'Email')
|
||||
if (item) {
|
||||
item.configBody = newValue
|
||||
}
|
||||
}
|
||||
},
|
||||
systemPhone: {
|
||||
get() {
|
||||
const item = this.systemConfig.find(x => x.configName == 'Phone')
|
||||
return item ? item.configBody : ''
|
||||
},
|
||||
set(newValue) {
|
||||
const item = this.systemConfig.find(x => x.configName == 'Phone')
|
||||
if (item) {
|
||||
item.configBody = newValue
|
||||
}
|
||||
}
|
||||
},
|
||||
systemDescription: {
|
||||
get() {
|
||||
const item = this.systemConfig.find(x => x.configName == 'SystemDescription')
|
||||
return item ? item.configBody : ''
|
||||
},
|
||||
set(newValue) {
|
||||
const item = this.systemConfig.find(x => x.configName == 'SystemDescription')
|
||||
if (item) {
|
||||
item.configBody = newValue
|
||||
}
|
||||
}
|
||||
},
|
||||
enableSystemRegister:{
|
||||
get(){
|
||||
const item = this.systemConfig.find(x => x.configName == 'RegisterConfig')
|
||||
return item ? JSON.parse(item.configBody).RegisterOn : false
|
||||
},
|
||||
set(newValue){
|
||||
const item = this.systemConfig.find(x => x.configName == 'RegisterConfig')
|
||||
if (item) {
|
||||
let jsonBody = JSON.parse(item.configBody)
|
||||
jsonBody.RegisterOn = newValue
|
||||
item.configBody = JSON.stringify(jsonBody)
|
||||
}
|
||||
}
|
||||
},
|
||||
enableSystemRegisterEmailValidate:{
|
||||
get(){
|
||||
const item = this.systemConfig.find(x => x.configName == 'RegisterConfig')
|
||||
return item ? JSON.parse(item.configBody).Emailvalidate : false
|
||||
},
|
||||
set(newValue){
|
||||
const item = this.systemConfig.find(x => x.configName == 'RegisterConfig')
|
||||
if (item) {
|
||||
let jsonBody = JSON.parse(item.configBody)
|
||||
jsonBody.Emailvalidate = newValue
|
||||
item.configBody = JSON.stringify(jsonBody)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.systemConfig = this.$store.state.config.systemconfig
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user