头像上传功能、性别选择

This commit is contained in:
橙子
2022-10-13 23:55:21 +08:00
parent 3555b08fe8
commit 8456320884
119 changed files with 51 additions and 31 deletions

View File

@@ -0,0 +1,25 @@
<template>
<material-card color="primary" icon="mdi-account-outline">
<template #title>
菜单管理 <small class="text-body-1">菜单可分配一个接口</small>
</template>
<ccTreeview></ccTreeview>
</material-card>
</template>
<script>
export default {
created() {
},
data: () => ({
}),
methods: {
},
};
</script>

View File

@@ -0,0 +1,39 @@
<template>
<material-card color="primary" icon="mdi-account-outline">
<template #title>
接口管理 <small class="text-body-1">接口可被菜单拥有</small>
</template>
<ccTable
:defaultItem="defaultItem"
:headers="headers"
:axiosUrls="axiosUrls"
></ccTable>
</material-card>
</template>
<script>
import userApi from "../api/userApi"
export default {
created(){this.init()},
methods:{
init(){
userApi.GetAxiosByRouter(this.$route.path).then(resp=>{
this.axiosUrls=resp.data;
})
}
},
data: () => ({
axiosUrls: {
},
headers: [
{ text: "编号", align: "start", value: "id" },
{ text: "接口名", value: "mould_name", sortable: false },
{ text: "接口地址", value: "url", sortable: false },
{ text: "操作", value: "actions", sortable: false },
],
defaultItem: {
mould_name: "get",
url: "/get/gettest",
},
}),
};
</script>

View File

@@ -0,0 +1,51 @@
<template>
<material-card color="primary" icon="mdi-account-tie">
<template #title>
角色管理 <small class="text-body-1">角色可分配多个菜单</small>
</template>
<ccTable
:defaultItem="defaultItem"
:headers="headers"
:axiosUrls="axiosUrls"
:btnEnable="btnEnable"
>
</ccTable>
</material-card>
</template>
<script>
import { getBtn } from "../util/btnHandle";
export default {
created() {
this.init();
},
methods: {
init() {
this.btnEnable = getBtn("role")
this.axiosUrls = {
get: "/role/GetList",
update: "/role/Update",
del: "/role/DeleteList",
add: "/role/Add",
};
}
},
data: () => ({
start: true,
axiosUrls: {
},
btnEnable:{},
headers: [
// { text: "编号", align: "start", value: "id" },
{ text: "角色编号", value: "roleCode", sortable: false },
{ text: "角色名", value: "roleName", sortable: false },
// { text: "云盘地址", value: "file_path", sortable: false },
// { text: "简介", value: "introduce", sortable: false },
{ text: "操作", value: "actions", sortable: false },
],
defaultItem: {
role_name: "",
introduce: "",
},
}),
};
</script>

View File

@@ -0,0 +1,128 @@
<template>
<v-row>
<v-col cols="12">
<material-card color="primary" icon="mdi-account-outline">
<template #title>
角色菜单分配管理
<small class="text-body-1"
>你可以在这里多角色分配多菜单/选中一个可查看</small
>
</template>
<v-divider></v-divider>
<app-btn dark class="ma-4" @click="showAll"> 展开全部</app-btn>
<app-btn class="my-4 mr-4" @click="setMenu">确定分配</app-btn>
<app-btn class="my-4" color="secondary" @click="clear"
>清空选择</app-btn
></material-card
>
</v-col>
<v-col cols="12" md="4" lg="4">
<v-card class="mx-auto" width="100%">
<v-treeview
selectable
:items="RoleItems"
v-model="selectionRole"
return-object
open-all
hoverable
item-text="roleName"
>
</v-treeview>
</v-card>
</v-col>
<v-col cols="12" md="8" lg="8">
<v-card class="mx-auto" width="100%">
<v-treeview
ref="tree"
open-on-click
selectable
:items="Menuitems"
selection-type="independent"
v-model="selectionMenu"
return-object
open-all
hoverable
item-text="menuName"
>
<template v-slot:prepend="{ item }">
<v-icon>
{{ item.menuIcon }}
</v-icon>
</template>
<template v-slot:append="{ item }">
<app-btn v-if="item.menuType==0">路由:{{ item.router }}</app-btn>
<app-btn v-if="item.menuType==1" color="secondary">权限:{{ item.permissionCode }}</app-btn>
</template>
</v-treeview>
</v-card></v-col
>
</v-row>
</template>
<script>
import roleApi from "../api/roleApi";
import menuApi from "../api/menuApi";
export default {
created() {
this.init();
},
watch: {
selectionRole: {
handler(val, oldVal) {
if (val.length == 1) {
roleApi.getInMenuByRoleId(val[0].id).then((resp) => {
if (resp.data.menus == null) {
this.selectionMenu = [];
} else {
this.selectionMenu = resp.data.menus;
}
});
}
},
deep: true,
},
},
methods: {
showAll() {
this.$refs.tree.updateAll(true);
},
clear() {
this.selectionMenu = [];
this.selectionRole = [];
},
setMenu() {
var roleIds = [];
var menuIds = [];
this.selectionRole.forEach((ele) => {
roleIds.push(ele.id);
});
this.selectionMenu.forEach((ele) => {
menuIds.push(ele.id);
});
roleApi.giveRoleSetMenu(roleIds, menuIds).then((resp) => {
this.$dialog.notify.info(resp.message, {
position: "top-right",
timeout: 5000,
});
});
},
init() {
roleApi.getList().then((resp) => {
this.RoleItems = resp.data;
});
menuApi.getMenuTree().then((resp) => {
this.Menuitems = resp.data;
});
},
},
data: () => ({
selectionMenu: [],
selectionRole: [],
RoleItems: [],
Menuitems: [],
}),
};
</script>

View File

@@ -0,0 +1,121 @@
<template>
<material-card color="primary" icon="mdi-account-outline">
<template #title>
用户管理 <small class="text-body-1">用户可拥有多个角色</small>
</template>
<ccCombobox headers="设置角色" :items="roleItems" @select="getSelect" itemText="roleName">
<template v-slot:save>
<v-btn @click="setRole" color="blue darken-1" text> 保存</v-btn>
</template>
</ccCombobox>
<ccTable :defaultItem="defaultItem" :headers="headers" :axiosUrls="axiosUrls" :btnEnable="btnEnable"
@selected="getTableSelect">
<template v-slot:action="{ item }">
<v-icon small class="mr-2" @click="showItem(item)"> mdi-eye </v-icon>
</template>
</ccTable>
</material-card>
</template>
<script>
import userApi from "../api/userApi";
import roleApi from "../api/roleApi";
import { getBtn } from "../util/btnHandle";
export default {
created() {
this.init();
},
methods: {
async showItem(item) {
var strInfo = "";
userApi.GetRoleListByUserId(item.id).then(async (resp) => {
var roleData = resp.data;
strInfo += "拥有的角色:<br>";
if (roleData != null) {
roleData.forEach((u) => {
strInfo += u.roleName + "<br>";
});
}
strInfo += "<hr>";
Object.keys(item).forEach(async function (key) {
strInfo += key + ":" + item[key] + "<br>";
});
await this.$dialog.confirm({
text: strInfo,
title: "信息详情",
actions: {
true: "关闭",
},
});
});
},
init() {
//这里可以遍历后台的菜单code根据对应的菜单code来给axiosUrls的增删改查赋值即可
this.btnEnable = getBtn("user")
this.axiosUrls = {
get: "/user/GetList",
update: "/user/Update",
del: "/user/DeleteList",
add: "/user/Add",
};
roleApi.getList().then((resp) => {
this.roleItems = JSON.parse(JSON.stringify(resp.data));
});
},
setRole() {
var userIds = [];
var roleIds = [];
this.TableSelect.forEach((item) => {
userIds.push(item.id);
});
this.select.forEach((item) => {
roleIds.push(item.id);
});
userApi.GiveUserSetRole(userIds, roleIds).then((resp) => {
this.$dialog.notify.success(resp.message, {
position: "top-right",
timeout: 5000,
});
});
},
getTableSelect(data) {
this.TableSelect = data;
},
getSelect(data) {
this.select = data;
},
},
data: () => ({
btnEnable: [],
TableSelect: [],
select: [],
roleItems: [],
axiosUrls: {},
headers: [
{ text: "用户名", value: "userName", sortable: false },
{ text: "图标", value: "icon", sortable: false },
{ text: "昵称", value: "nick", sortable: true },
{ text: "邮箱", value: "email", sortable: true },
{ text: "IP", value: "ip", sortable: false },
{ text: "年龄", value: "age", sortable: false },
{ text: "地址", value: "address", sortable: false },
{ text: "电话", value: "phone", sortable: false },
{ text: "操作", value: "actions", sortable: false },
],
defaultItem: {
username: "test",
password: "123",
icon: "",
nick: "橙子",
age: 18,
address: "中国",
phone: "123456789",
},
}),
};
</script>

View File

@@ -0,0 +1,442 @@
<template>
<v-container
id="dashboard-view"
fluid
tag="section"
>
<v-row>
<v-col cols="12">
<v-row>
<v-col
v-for="(chart, i) in charts"
:key="`chart-${i}`"
cols="12"
md="6"
lg="4"
>
<material-chart-card
:color="chart.color"
:data="chart.data"
:options="chart.options"
:responsive-options="chart.responsiveOptions"
:title="chart.title"
:type="chart.type"
>
<template #subtitle>
<div class="font-weight-light text--secondary">
<div v-html="chart.subtitle" />
</div>
</template>
<template #actions>
<v-icon
class="mr-1"
small
>
mdi-clock-outline
</v-icon>
<span
class="text-caption grey--text font-weight-light"
v-text="chart.time"
/>
</template>
</material-chart-card>
</v-col>
</v-row>
</v-col>
<v-col
v-for="({ actionIcon, actionText, ...attrs }, i) in stats"
:key="i"
cols="12"
md="6"
lg="3"
>
<material-stat-card v-bind="attrs">
<template #actions>
<v-icon
class="mr-2"
small
v-text="actionIcon"
/>
<div class="text-truncate">
{{ actionText }}
</div>
</template>
</material-stat-card>
</v-col>
<v-col
cols="12"
md="6"
>
<material-card
color="orange"
full-header
>
<template #heading>
<div class="pa-8 white--text">
<div class="text-h4 font-weight-light">
Employees Stats
</div>
<div class="text-caption">
New employees on 15th September, 2016
</div>
</div>
</template>
<v-card-text>
<v-data-table
:headers="headers"
:items="items"
/>
</v-card-text>
</material-card>
</v-col>
<v-col
cols="12"
md="6"
>
<material-card
color="accent"
full-header
>
<template #heading>
<v-tabs
v-model="tabs"
background-color="transparent"
slider-color="white"
class="pa-8"
>
<span
class="subheading font-weight-light mx-3"
style="align-self: center"
>Tasks:</span>
<v-tab class="mr-3">
<v-icon class="mr-2">
mdi-bug
</v-icon>
Bugs
</v-tab>
<v-tab class="mr-3">
<v-icon class="mr-2">
mdi-code-tags
</v-icon>
Website
</v-tab>
<v-tab>
<v-icon class="mr-2">
mdi-cloud
</v-icon>
Server
</v-tab>
</v-tabs>
</template>
<v-tabs-items
v-model="tabs"
background-color="transparent"
>
<v-tab-item
v-for="n in 3"
:key="n"
>
<v-card-text>
<template v-for="(task, i) in tasks[tabs]">
<v-row
:key="i"
align="center"
class="flex-nowrap"
>
<v-col cols="1">
<v-list-item-action>
<v-simple-checkbox
v-model="task.value"
color="secondary"
/>
</v-list-item-action>
</v-col>
<v-col
class="font-weight-light"
cols="8"
v-text="task.text"
/>
<v-col
cols="auto"
class="text-right"
>
<v-icon class="mx-1">
mdi-pencil
</v-icon>
<v-icon
class="mx-1"
color="error"
>
mdi-close
</v-icon>
</v-col>
</v-row>
</template>
</v-card-text>
</v-tab-item>
</v-tabs-items>
</material-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
// Utilities
// import { get } from 'vuex-pathify'
import Vue from 'vue'
const lineSmooth = Vue.chartist.Interpolation.cardinal({
tension: 0,
})
export default {
name: 'DashboardView',
data: () => ({
charts: [{
type: 'Bar',
color: 'primary',
title: 'Website Views',
subtitle: 'Last Campaign Performance',
time: 'updated 10 minutes ago',
data: {
labels: ['Ja', 'Fe', 'Ma', 'Ap', 'Mai', 'Ju', 'Jul', 'Au', 'Se', 'Oc', 'No', 'De'],
series: [
[542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895],
],
},
options: {
axisX: {
showGrid: false,
},
low: 0,
high: 1000,
chartPadding: {
top: 0,
right: 5,
bottom: 0,
left: 0,
},
},
responsiveOptions: [
['screen and (max-width: 640px)', {
seriesBarDistance: 5,
axisX: {
labelInterpolationFnc: function (value) {
return value[0]
},
},
}],
],
}, {
type: 'Line',
color: 'success',
title: 'Daily Sales',
subtitle: '<i class="mdi mdi-arrow-up green--text"></i><span class="green--text">55%</span>&nbsp;increase in today\'s sales',
time: 'updated 4 minutes ago',
data: {
labels: ['12am', '3pm', '6pm', '9pm', '12pm', '3am', '6am', '9am'],
series: [
[230, 750, 450, 300, 280, 240, 200, 190],
],
},
options: {
lineSmooth,
low: 0,
high: 1000, // creative tim: we recommend you to set the high sa the biggest value + something for a better look
chartPadding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
},
}, {
type: 'Line',
color: 'info',
title: 'Completed Tasks',
subtitle: 'Last Campaign Performance',
time: 'campaign sent 26 minutes ago',
data: {
labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
series: [
[12, 17, 7, 17, 23, 18, 38],
],
},
options: {
lineSmooth,
low: 0,
high: 50, // creative tim: we recommend you to set the high sa the biggest value + something for a better look
chartPadding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
},
}],
headers: [
{
sortable: false,
text: 'ID',
value: 'id',
},
{
sortable: false,
text: 'Name',
value: 'name',
},
{
sortable: false,
text: 'Salary',
value: 'salary',
align: 'right',
},
{
sortable: false,
text: 'Country',
value: 'country',
align: 'right',
},
{
sortable: false,
text: 'City',
value: 'city',
align: 'right',
},
],
items: [
{
id: 1,
name: 'Dakota Rice',
country: 'Niger',
city: 'Oud-Tunrhout',
salary: '$35,738',
},
{
id: 2,
name: 'Minerva Hooper',
country: 'Curaçao',
city: 'Sinaai-Waas',
salary: '$23,738',
},
{
id: 3,
name: 'Sage Rodriguez',
country: 'Netherlands',
city: 'Overland Park',
salary: '$56,142',
},
{
id: 4,
name: 'Philip Chanley',
country: 'Korea, South',
city: 'Gloucester',
salary: '$38,735',
},
{
id: 5,
name: 'Doris Greene',
country: 'Malawi',
city: 'Feldkirchen in Kārnten',
salary: '$63,542',
},
],
stats: [
{
actionIcon: 'mdi-alert',
actionText: 'Get More Space...',
color: '#FD9A13',
icon: 'mdi-sofa-single',
title: 'Bookings',
value: '184',
},
{
actionIcon: 'mdi-tag',
actionText: 'Tracked from Google Analytics',
color: 'primary',
icon: 'mdi-chart-bar',
title: 'Website Visits',
value: '75.521',
},
{
actionIcon: 'mdi-calendar-range',
actionText: 'Last 24 Hours',
color: 'success',
icon: 'mdi-store',
title: 'Revenue',
value: '$34,245',
},
{
actionIcon: 'mdi-history',
actionText: 'Just Updated',
color: 'info',
icon: 'mdi-twitter',
title: 'Followers',
value: '+245',
},
],
tabs: 0,
tasks: {
0: [
{
text: 'Sign contract for "What are conference organizers afraid of?"',
value: true,
},
{
text: 'Lines From Great Russian Literature? Or E-mails From My Boss?',
value: false,
},
{
text: 'Flooded: One year later, assessing what was lost and what was found when a ravaging rain swept through metro Detroit',
value: false,
},
{
text: 'Create 4 Invisible User Experiences you Never Knew About',
value: true,
},
],
1: [
{
text: 'Flooded: One year later, assessing what was lost and what was found when a ravaging rain swept through metro Detroit',
value: true,
},
{
text: 'Sign contract for "What are conference organizers afraid of?"',
value: false,
},
],
2: [
{
text: 'Lines From Great Russian Literature? Or E-mails From My Boss?',
value: false,
},
{
text: 'Flooded: One year later, assessing what was lost and what was found when a ravaging rain swept through metro Detroit',
value: true,
},
{
text: 'Sign contract for "What are conference organizers afraid of?"',
value: true,
},
],
},
}),
computed: {
// sales: get('sales/sales'),
// totalSales () {
// return this.sales.reduce((acc, val) => acc + val.salesInM, 0)
// },
},
}
</script>

View File

@@ -0,0 +1,51 @@
<template>
<v-row>
<v-col cols="12">
<material-card color="primary" icon="mdi-account-outline">
<template #title>
企业云盘 <small class="text-body-1">选择你的角色空间</small>
</template>
</material-card>
</v-col>
<v-col cols="6" xl="1" sm="3" v-for="item in roleNameList" :key="item" class="text-center" @click="toInfo(item.id,item.file_path)">
<v-card>
<v-icon size="100">mdi-briefcase-account</v-icon>
</v-card>
<v-chip class="ma-2" color="primary" text-color="white">
{{item.role_name}}
</v-chip>
</v-col>
<v-col cols="6">
<v-card> </v-card>
</v-col>
</v-row>
</template>
<script>
import userApi from "../api/userApi";
export default {
created() {
this.init();
},
methods: {
toInfo(roleId,filePath)
{
this.$store.dispatch("Set_BasePath", filePath);
this.$router.push(`/paninfo?roleId=${roleId}`);
},
init(){
userApi.GetUserInRolesByHttpUser().then(response=>{
const resp=response.data;
this.roleNameList=resp.roles
})
}
},
data: () => ({
roleNameList:[],
selected: [],
}),
};
</script>

View File

@@ -0,0 +1,115 @@
<template>
<v-row>
<v-col cols="12">
<material-card color="primary" icon="mdi-account-outline">
<template #title>
XX-云盘空间 <small class="text-body-1">浏览属于你的空间</small>
</template>
<v-divider></v-divider>
<router-link to="/pan">
<app-btn dark class="ma-4">返回 </app-btn></router-link
>
<app-btn class="my-4 mr-4">全部选中</app-btn>
<app-btn class="my-4 mr-4">清空选中</app-btn>
<app-btn class="my-4" color="secondary" @click="download"
>批量下载</app-btn
></material-card
>
</v-col>
<v-col
cols="6"
xl="1"
sm="3"
v-for="i in dirList"
:key="i"
class="text-center"
>
<v-card>
<v-icon size="100" @click="enter(i)">mdi-briefcase-account</v-icon>
</v-card>
<v-chip class="ma-2" text-color="white">
<v-checkbox
v-model="selected"
color="primary"
:label="i"
:value="i"
></v-checkbox>
</v-chip>
</v-col>
<v-col
cols="6"
xl="1"
sm="3"
v-for="i in fileList"
:key="i"
class="text-center"
>
<v-card>
<v-icon size="100">mdi-badge-account-outline</v-icon>
</v-card>
<v-chip class="ma-2" text-color="white">
<v-checkbox
v-model="selected"
color="primary"
:label="i"
:value="i"
></v-checkbox>
</v-chip>
</v-col>
</v-row>
</template>
<script>
import panApi from "../api/panApi";
export default {
data: () => ({
dirList: [],
fileList: [],
selected: [],
baseurl:""
}),
created() {
this.init();
},
destroyed(){
this.$store.dispatch("Set_ExtendPath","");
},
mounted() {
this.baseurl = process.env.VUE_APP_BASE_API;
},
methods: {
download()
{
panApi.Download(this.$store.getters.path,this.selected) .then(res => {
console.log(res.data)
//这里linux有问题可能是nginx的问题先直接写网关
window.open("http://ccnetcore.com:19000/api/file/get/"+res.data);
})
},
enter(enterName) {
this.$store.dispatch("Add_ExtendPath", enterName);
// console.log(this.$store.state.pan.extendPath);
this.init();
},
init() {
this.selected=[];
// this.$store.dispatch("Set_ExtendPath","");
// console.log(this.$store.state.pan.basePath);
// console.log(this.$store.state.pan.extendPath);
// console.log(this.$store.getters.path);
panApi.GetPanFiles(this.$store.getters.path).then((response) => {
const resp = response.data;
this.dirList = resp.dirList;
this.fileList = resp.fileList;
});
},
},
};
</script>

View File

@@ -0,0 +1,170 @@
<template>
<v-card class="auth-card">
<!-- logo -->
<v-card-title class="d-flex align-center justify-center py-7">
<router-link to="/" class="d-flex align-center">
<v-img
:src="require('@/assets/logo.svg')"
max-height="30px"
max-width="30px"
alt="logo"
contain
class="me-3"
></v-img>
<h2 class="text-2xl font-weight-semibold">Yi-Framework</h2>
</router-link>
</v-card-title>
<!-- title -->
<v-card-text>
<p class="text-2xl font-weight-semibold text--primary mb-2">
欢迎来到CCNetCore! 👋🏻
</p>
<p class="mb-2">登入你的用户开始畅游一切</p>
</v-card-text>
<!-- login form -->
<v-card-text>
<v-form>
<v-text-field
v-model="form.username"
outlined
label="用户"
placeholder="123456789@qq.com"
counter="20"
></v-text-field>
<v-text-field
v-model="form.password"
outlined
:type="isPasswordVisible ? 'text' : 'password'"
label="密码"
placeholder="············"
:append-icon="isPasswordVisible ? 'mdi-eye' : 'mdi-eye-off'"
@click:append="isPasswordVisible = !isPasswordVisible"
></v-text-field>
<div class="d-flex align-center justify-space-between flex-wrap">
<v-checkbox label="记住密码" hide-details class="me-3 mt-1">
</v-checkbox>
<!-- forgot link -->
<a href="javascript:void(0)" class="mt-1"> 忘记密码? </a>
</div>
<v-btn
block
color="primary"
@click="login"
class="mt-6"
:loading="loader"
:disabled="btn_dis"
>
登录
</v-btn>
</v-form>
</v-card-text>
<!-- create new account -->
<v-card-text class="d-flex align-center justify-center flex-wrap mt-2">
<span class="me-2"> 没有我们的账号? </span>
<router-link :to="{ path: '/register' }"> 注册账号 </router-link>
</v-card-text>
<!-- divider -->
<v-card-text class="d-flex align-center mt-2">
<v-divider></v-divider>
<span class="mx-5">or</span>
<v-divider></v-divider>
</v-card-text>
<!-- social links -->
<v-card-actions class="d-flex justify-center">
<v-btn v-for="link in socialLink" :key="link.icon" icon class="ms-1">
<v-icon :color="$vuetify.theme.dark ? link.colorInDark : link.color">
{{ link.icon }}
</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
created() {
this.enterSearch();
},
data: () => ({
btn_dis: false,
loader: null,
socialLink: [
{
icon: "mdi-qqchat",
color: "#8D5EE0",
colorInDark: "#8D5EE0",
},
{
icon: "mdi-facebook",
color: "#4267b2",
colorInDark: "#4267b2",
},
{
icon: "mdi-twitter",
color: "#1da1f2",
colorInDark: "#1da1f2",
},
{
icon: "mdi-github",
color: "#272727",
colorInDark: "#fff",
},
{
icon: "mdi-google",
color: "#db4437",
colorInDark: "#db4437",
},
],
isPasswordVisible: false,
form: {
username: "",
password: "",
},
}),
methods: {
enterSearch() {
document.onkeydown = (e) => {
//13表示回车键baseURI是当前页面的地址为了更严谨也可以加别的可以打印e看一下
if (e.keyCode === 13 && e.target.baseURI.match("/")) {
//回车后执行搜索方法
this.login();
}
};
},
login() {
this.loader = true;
this.btn_dis = true;
this.$store
.dispatch("Login", this.form)
.then((resp) => {
if (resp.status) {
this.$router.push("/");
} else {
this.loader = null;
this.btn_dis = false;
this.$dialog.notify.error(resp.message, {
position: "top-right",
timeout: 5000,
});
}
})
.catch((error) => {
this.loader = false;
this.btn_dis = false;
});
},
},
};
</script>

View File

@@ -0,0 +1,183 @@
<template>
<v-card class="auth-card">
<!-- logo -->
<v-card-title class="d-flex align-center justify-center py-7">
<router-link to="/" class="d-flex align-center">
<v-img
:src="require('@/assets/logo.svg')"
max-height="30px"
max-width="30px"
alt="logo"
contain
class="me-3"
></v-img>
<h2 class="text-2xl font-weight-semibold">Yi-Framework</h2>
</router-link>
</v-card-title>
<!-- title -->
<v-card-text>
<p class="text-2xl font-weight-semibold text--primary mb-1">
注册-从这里开始 🚀
</p>
<p class="mb-1">加入我们获得一个有趣的灵魂</p>
</v-card-text>
<!-- login form -->
<v-card-text>
<v-form>
<v-text-field
v-model="form.username"
outlined
label="用户名"
placeholder="cc"
class="mb-1"
counter="20"
></v-text-field>
<v-text-field
v-model="form.phone"
outlined
label="电话"
placeholder="12345678901"
class="mb-1"
>
</v-text-field>
<v-row>
<v-col cols="9">
<v-text-field
v-model="code"
outlined
label="验证码"
placeholder="123456"
class="mb-1"
>
</v-text-field>
</v-col>
<v-col cols="3">
<v-btn color="secondary" @click="sendSMS" class="mb-1 mt-1" :disabled="is_en">验证码</v-btn>
</v-col>
</v-row>
<v-text-field
v-model="form.password"
outlined
:type="isPasswordVisible ? 'text' : 'password'"
label="密码"
placeholder="············"
:append-icon="isPasswordVisible ? 'mdi-eye' : 'mdi-eye-off'"
@click:append="isPasswordVisible = !isPasswordVisible"
></v-text-field>
<v-checkbox hide-details class="mt-1">
<template #label>
<div class="d-flex align-center flex-wrap">
<span class="me-2">我同意</span
><a href="javascript:void(0)">协议 &amp; 策略</a>
</div>
</template>
</v-checkbox>
<v-btn block color="primary" class="mt-6" @click="register">
注册
</v-btn>
</v-form>
</v-card-text>
<!-- create new account -->
<v-card-text class="d-flex align-center justify-center flex-wrap mt-2">
<span class="me-2"> 已经存在账号? </span>
<router-link :to="{ path: '/login' }"> 跳转登录 </router-link>
</v-card-text>
<!-- divider -->
<v-card-text class="d-flex align-center mt-2">
<v-divider></v-divider>
<span class="mx-5">or</span>
<v-divider></v-divider>
</v-card-text>
<!-- social link -->
<v-card-actions class="d-flex justify-center">
<v-btn v-for="link in socialLink" :key="link.icon" icon class="ms-1">
<v-icon :color="$vuetify.theme.dark ? link.colorInDark : link.color">
{{ link.icon }}
</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
import accoutAPI from "../api/accountApi";
export default {
methods: {
sendSMS() {
this.is_en=true
accoutAPI.SendSMS(this.form.phone).then(resp=>{
if (resp.status) {
this.$dialog.notify.success(resp.msg, {
position: "top-right",
timeout: 5000,
});
}
});
},
register() {
accoutAPI
.register(
this.form.username,
this.form.password,
this.form.phone,
this.code
)
.then((resp) => {
if (resp.status) {
this.$dialog.notify.success(resp.msg, {
position: "top-right",
timeout: 5000,
});
this.$router.push("/login/");
}
});
},
},
data: () => ({
socialLink: [
{
icon: "mdi-qqchat",
color: "#8D5EE0",
colorInDark: "#8D5EE0",
},
{
icon: "mdi-facebook",
color: "#4267b2",
colorInDark: "#4267b2",
},
{
icon: "mdi-twitter",
color: "#1da1f2",
colorInDark: "#1da1f2",
},
{
icon: "mdi-github",
color: "#272727",
colorInDark: "#fff",
},
{
icon: "mdi-google",
color: "#db4437",
colorInDark: "#db4437",
},
],
isPasswordVisible: false,
code: "",
is_en:false,
form: {
phone: "",
username: "",
password: "",
},
}),
};
</script>

View File

@@ -0,0 +1,362 @@
<template>
<v-container id="user-profile-view" fluid tag="section">
<v-row justify="center">
<v-col cols="12" md="4">
<app-card class="mt-4 text-center">
<ccAvatar
:size="128"
class="rounded-circle elevation-6 mt-n12 d-inline-block"
></ccAvatar>
<v-card-text class="text-center">
<h6 class="text-h6 mb-2 text--secondary">
{{ userInfo.userName }}
</h6>
<h4 class="text-h4 mb-3 text--primary">{{ userInfo.nick }}</h4>
<p class="text--secondary">{{ userInfo.introduction }}</p>
<input
type="file"
ref="imgFile"
@change="uploadImage()"
class="d-none"
/>
<v-btn
class="mr-4"
@click="choiceImg"
color="primary"
min-width="100"
rounded
>
编辑头像
</v-btn>
<v-btn color="primary" min-width="100" rounded> 绑定QQ </v-btn>
</v-card-text>
</app-card>
</v-col>
<v-col cols="12" md="8">
<material-card color="primary" icon="mdi-account-outline">
<template #title>
用户信息 <small class="text-body-1">编辑属于你的一切</small>
</template>
<v-form>
<v-tabs class="pl-4" v-model="tab">
<v-tab href="#tab-1">
账户信息
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2">
额外信息
<v-icon>mdi-account-box</v-icon>
</v-tab>
<v-tab href="#tab-3">
修改密码
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item :value="'tab-1'">
<v-card class="py-0">
<v-card-text>
<div>Account Information</div>
<v-row>
<v-col cols="12" md="4">
<v-text-field
color="purple"
label="用户名"
v-model="editInfo.userName"
disabled
/>
</v-col>
<v-col cols="12" md="4">
<v-text-field
color="purple"
label="昵称"
v-model="editInfo.nick"
/>
</v-col>
<v-col cols="12" md="4">
<v-text-field
color="purple"
label="邮箱"
v-model="editInfo.email"
/>
</v-col>
<v-col cols="12" md="6">
<v-text-field
color="purple"
label="住址"
v-model="editInfo.address"
/>
</v-col>
<v-col cols="12" md="6">
<v-text-field
color="purple"
label="电话"
type="number"
v-model="editInfo.phone"
/>
</v-col>
<v-col cols="12">
<v-textarea
v-model="editInfo.introduction"
color="purple"
label="简介"
value="空空如也Ta什么也没有留下"
/>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-tab-item>
<v-tab-item :value="'tab-2'">
<v-card class="py-0 mx-auto">
<v-card-text>
<div>Extra Information</div>
<v-row>
<v-col cols="12">
<v-list two-line>
<v-list-item>
<v-list-item-icon>
<v-icon color="secondary"> mdi-phone </v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>等级</v-list-item-title>
<v-list-item-subtitle>100</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-icon>
<v-icon>mdi-message-text</v-icon>
</v-list-item-icon>
</v-list-item>
<v-list-item>
<v-list-item-action></v-list-item-action>
<v-list-item-content>
<v-list-item-title>经验</v-list-item-title>
<v-list-item-subtitle>1000</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-icon>
<v-icon>mdi-message-text</v-icon>
</v-list-item-icon>
</v-list-item>
<v-divider inset></v-divider>
<v-list-item>
<v-list-item-icon>
<v-icon color="secondary"> mdi-lock </v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>拥有角色</v-list-item-title>
<v-list-item-subtitle>
<v-row>
<v-col
v-for="item in roleInfo"
:key="item.id"
cols="6"
sm="3"
md="1"
>{{ item.roleName }}</v-col
>
</v-row>
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action></v-list-item-action>
<v-list-item-content>
<v-list-item-title>拥有菜单</v-list-item-title>
<v-list-item-subtitle>
<v-row>
<v-col
v-for="item in menuInfo"
:key="item.id"
cols="6"
sm="3"
md="1"
>{{ item.menuName }}</v-col
>
</v-row>
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider inset></v-divider>
<v-list-item>
<v-list-item-icon>
<v-icon color="secondary"> mdi-email </v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>等待更新</v-list-item-title>
<v-list-item-subtitle>1000</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action></v-list-item-action>
<v-list-item-content>
<v-list-item-title>等待更新</v-list-item-title>
<v-list-item-subtitle>500</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action></v-list-item-action>
<v-list-item-content>
<v-btn dark color="primary" class="ml-0" dense>
等待更新
</v-btn>
</v-list-item-content>
</v-list-item>
<v-divider inset></v-divider>
</v-list>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-tab-item>
<v-tab-item :value="'tab-3'">
<v-card>
<v-card-text>
<div>Password Information</div>
<v-col cols="12">
<v-text-field
style="width: 80%"
label="原密码"
v-model="oldPassword"
outlined
clearable
></v-text-field>
<v-text-field
required
style="width: 80%"
:counter="120"
v-model="newPassword"
:disabled="dis_newPassword"
label="新密码"
></v-text-field>
</v-col>
</v-card-text>
</v-card>
</v-tab-item>
</v-tabs-items>
<v-col cols="12" class="text-right">
<v-btn color="primary" class="ma-4" min-width="100"> 清空 </v-btn>
<v-btn color="secondary" @click="save()" min-width="100">
保存
</v-btn>
</v-col>
</v-form>
</material-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import fileApi from "../api/fileApi";
import accountApi from "../api/accountApi";
export default {
name: "UserProfileView",
data: () => ({
tab: "tab-1",
userInfo: {},
editInfo: {},
newPassword: "",
oldPassword: "",
dis_newPassword: true,
roleInfo: [],
menuInfo: [],
}),
created() {
this.init();
},
watch: {
oldPassword: {
handler(val, oldVal) {
if (val != "") {
this.dis_newPassword = false;
} else {
this.dis_newPassword = true;
}
},
deep: true, //true 深度监听
},
},
methods: {
save() {
if (this.newPassword != "") {
accountApi
.updatePassword(this.oldPassword, this.newPassword)
.then((resp) => {
if (resp.status) {
this.$dialog.notify.success(resp.message, {
position: "top-right",
timeout: 5000,
});
} else {
this.$dialog.notify.error(resp.message, {
position: "top-right",
timeout: 5000,
});
}
this.init();
});
} else {
accountApi.updateUserByHttp(this.editInfo).then((resp) => {
this.init();
});
}
},
init() {
this.newPassword = "";
this.oldPassword = "";
accountApi.getUserAllInfo().then((resp) => {
this.userInfo = resp.data.user;
this.userInfo.password = "";
this.editInfo = Object.assign({}, this.userInfo);
this.roleInfo = resp.data.roles;
this.menuInfo = resp.data.menus;
this.$store.commit("SET_NEW_USER", this.userInfo);
});
},
choiceImg() {
this.$refs.imgFile.dispatchEvent(new MouseEvent("click"));
},
uploadImage() {
//修改头像需要先上传头像修改editInfo的头像信息即可
const file = this.$refs.imgFile.files[0];
let formData = new FormData();
formData.append("file", file);
fileApi.UploadImage(formData).then((resp) => {
this.editInfo.icon=resp.data
this.$dialog.notify.success("头像加载成功,点击保存以设置", {
position: "top-right",
timeout: 5000,
});
this.$store.dispatch("SetIcon", this.editInfo.icon)
});
},
},
};
</script>