create logs page

This commit is contained in:
mahyargdz
2024-11-18 18:56:14 +03:30
parent 7583fe1cb9
commit f75f890fa5
8 changed files with 688 additions and 371 deletions
+87 -66
View File
@@ -3,10 +3,8 @@
fixed fixed
:minimize="minimize" :minimize="minimize"
:show="show" :show="show"
@update:show=" @update:show="(value) => $store.commit('admin/set', ['sidebarShow', value])"
(value) => >
$store.commit('admin/set', ['sidebarShow', value])
">
<CSidebarBrand class="d-md-down-none"> <CSidebarBrand class="d-md-down-none">
<a href="/" target="_blank"> <a href="/" target="_blank">
<span style="color: #fff">پرتال خبری</span> <span style="color: #fff">پرتال خبری</span>
@@ -20,68 +18,86 @@
<CSidebarNavItem <CSidebarNavItem
name="صفحه اصلی" name="صفحه اصلی"
:to="{ name: 'admin' }" :to="{ name: 'admin' }"
font-icon="fal fa-home" /> font-icon="fal fa-home"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت کاربران" name="مدیریت کاربران"
:to="{ name: 'admin-users' }" :to="{ name: 'admin-users' }"
v-if="hasPermission('superAdmin')" v-if="hasPermission('superAdmin')"
fontIcon="fal fa-users" fontIcon="fal fa-users"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت صفحات" name="مدیریت صفحات"
:to="{ name: 'admin-pages' }" :to="{ name: 'admin-pages' }"
v-if="hasPermission('categories')" v-if="hasPermission('categories')"
fontIcon="fal fa-file" fontIcon="fal fa-file"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت عملکرد" name="مدیریت عملکرد"
:to="{ name: 'admin-pdfManagement' }" :to="{ name: 'admin-pdfManagement' }"
v-if="hasPermission('categories')" v-if="hasPermission('categories')"
fontIcon="fal fa-file" fontIcon="fal fa-file"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت پرونده خبری" name="مدیریت پرونده خبری"
:to="{ name: 'admin-newsFile' }" :to="{ name: 'admin-newsFile' }"
v-if="hasPermission('newsFile')" v-if="hasPermission('newsFile')"
font-icon="fal fa-cabinet-filing" font-icon="fal fa-cabinet-filing"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت اخبار" name="مدیریت اخبار"
:to="{ name: 'admin-news' }" :to="{ name: 'admin-news' }"
v-if="hasPermission('news')" v-if="hasPermission('news')"
font-icon="fal fa-newspaper" font-icon="fal fa-newspaper"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت چند رسانه ای ها" name="مدیریت چند رسانه ای ها"
v-if="hasPermission('gallery')" v-if="hasPermission('gallery')"
:to="{ name: 'admin-gallery' }" :to="{ name: 'admin-gallery' }"
font-icon="fal fa-images" font-icon="fal fa-images"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت نظرسنجی ها" name="مدیریت نظرسنجی ها"
:to="{ name: 'admin-polls', query: { page: 1 } }" :to="{ name: 'admin-polls', query: { page: 1 } }"
font-icon="fal fa-poll-people" font-icon="fal fa-poll-people"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت انتخابات" name="مدیریت انتخابات"
:exact="false" :exact="false"
:to="{ name: 'admin-elections' }" :to="{ name: 'admin-elections' }"
v-if="hasPermission('elections')" v-if="hasPermission('elections')"
font-icon="fal fa-box-ballot" /> font-icon="fal fa-box-ballot"
/>
<CSidebarNavItem
name="مدیریت نشست ها"
:exact="false"
:to="{ name: 'admin-sessions' }"
v-if="hasPermission('superAdmin')"
font-icon="fal fa-solid fa-user"
/>
<CSidebarNavDropdown <CSidebarNavDropdown
name="میز خدمت" name="میز خدمت"
:show="Boolean(unreadMeetingReq)" :show="Boolean(unreadMeetingReq)"
v-if="hasPermission('superAdmin')" v-if="hasPermission('superAdmin')"
font-icon="fal fa-browser"> font-icon="fal fa-browser"
>
<CSidebarNavItem <CSidebarNavItem
name="درخواست های ملاقات با استاندار" name="درخواست های ملاقات با استاندار"
:exact="false" :exact="false"
@@ -90,7 +106,8 @@
? { text: unreadMeetingReq, color: 'danger' } ? { text: unreadMeetingReq, color: 'danger' }
: null : null
" "
:to="{ name: 'admin-meeting' }" /> :to="{ name: 'admin-meeting' }"
/>
</CSidebarNavDropdown> </CSidebarNavDropdown>
<!-- <CSidebarNavItem <!-- <CSidebarNavItem
@@ -102,16 +119,12 @@
<CSidebarNavDropdown <CSidebarNavDropdown
name="مدیریت پیام ها" name="مدیریت پیام ها"
:show=" :show="Boolean(unreadContactMessages + unreadNewsMessages)"
Boolean(
unreadContactMessages + unreadNewsMessages
)
"
v-if=" v-if="
hasPermission('comment-News') || hasPermission('comment-News') || hasPermission('comment-ContactUs')
hasPermission('comment-ContactUs')
" "
fontIcon="fal fa-envelope"> fontIcon="fal fa-envelope"
>
<CSidebarNavItem <CSidebarNavItem
v-if="hasPermission('comment-News')" v-if="hasPermission('comment-News')"
name="کامنت های اخبار" name="کامنت های اخبار"
@@ -127,7 +140,8 @@
:to="{ :to="{
name: 'admin-comments-type', name: 'admin-comments-type',
params: { type: 'News' }, params: { type: 'News' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
v-if="hasPermission('comment-ContactUs')" v-if="hasPermission('comment-ContactUs')"
name="پیام های تماس با ما" name="پیام های تماس با ما"
@@ -143,83 +157,100 @@
:to="{ :to="{
name: 'admin-comments-type', name: 'admin-comments-type',
params: { type: 'ContactUs' }, params: { type: 'ContactUs' },
}" /> }"
/>
</CSidebarNavDropdown> </CSidebarNavDropdown>
<CSidebarNavDropdown <CSidebarNavDropdown
name="تنظیمات" name="تنظیمات"
v-if="hasPermission('superAdmin')" v-if="hasPermission('superAdmin')"
fontIcon="fal fa-cog"> fontIcon="fal fa-cog"
>
<CSidebarNavItem <CSidebarNavItem
name="اخباری روی صفحه اصلی" name="اخباری روی صفحه اصلی"
:to="{ :to="{
name: 'admin-homePageNews', name: 'admin-homePageNews',
query: { portal: 'ostandari' }, query: { portal: 'ostandari' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت پیوندها" name="مدیریت پیوندها"
:to="{ name: 'admin-links' }" :to="{ name: 'admin-links' }"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="استاندار" name="استاندار"
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'manager' }, params: { details: 'manager' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت اسلایدر" name="مدیریت اسلایدر"
:to="{ name: 'admin-slider' }" :to="{ name: 'admin-slider' }"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="عکس شعار سال" name="عکس شعار سال"
:to="{ name: 'admin-yearBanner' }" /> :to="{ name: 'admin-yearBanner' }"
/>
<CSidebarNavItem <CSidebarNavItem
name="دکمه ستاد انتخابات" name="دکمه ستاد انتخابات"
:to="{ name: 'admin-electionBtn' }" /> :to="{ name: 'admin-electionBtn' }"
/>
<CSidebarNavItem <CSidebarNavItem
name="آدرس ایمیل و شبکه های اجتماعی" name="آدرس ایمیل و شبکه های اجتماعی"
:to="{ name: 'admin-socialLinks' }" /> :to="{ name: 'admin-socialLinks' }"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت مناسبت ها" name="مدیریت مناسبت ها"
:to="{ name: 'admin-occasion' }" :to="{ name: 'admin-occasion' }"
:exact="false" /> :exact="false"
/>
<CSidebarNavItem <CSidebarNavItem
name="مدیریت روز شمار" name="مدیریت روز شمار"
:to="{ name: 'admin-counterDay' }" /> :to="{ name: 'admin-counterDay' }"
/>
<CSidebarNavItem <CSidebarNavItem
name="پشتیبان گیری از سایت" name="پشتیبان گیری از سایت"
:to="{ name: 'admin-backup' }" /> :to="{ name: 'admin-backup' }"
/>
</CSidebarNavDropdown> </CSidebarNavDropdown>
<CSidebarNavDropdown <CSidebarNavDropdown
name="مدیریت صفحات خاص" name="مدیریت صفحات خاص"
v-if="hasPermission('contents')" v-if="hasPermission('contents')"
fontIcon="fal fa-file-alt"> fontIcon="fal fa-file-alt"
>
<CSidebarNavItem <CSidebarNavItem
name="صفحه اصلی" name="صفحه اصلی"
:to="{ :to="{
name: 'admin-homePageManagement', name: 'admin-homePageManagement',
query: { portal: 'ostandari' }, query: { portal: 'ostandari' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="صفحه عملکرد" name="صفحه عملکرد"
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'performance' }, params: { details: 'performance' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="صفحه سیمای استان" name="صفحه سیمای استان"
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'sima' }, params: { details: 'sima' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="صفحه درباره ما" name="صفحه درباره ما"
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'aboutus' }, params: { details: 'aboutus' },
}" /> }"
/>
<!-- <CSidebarNavItem--> <!-- <CSidebarNavItem-->
<!-- name="صفحه خدمات"--> <!-- name="صفحه خدمات"-->
<!-- :to="{ name: 'admin-contents-details' , params : {details : 'services'} }"--> <!-- :to="{ name: 'admin-contents-details' , params : {details : 'services'} }"-->
@@ -233,7 +264,8 @@
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'privacy' }, params: { details: 'privacy' },
}" /> }"
/>
<!-- <CSidebarNavItem--> <!-- <CSidebarNavItem-->
<!-- name="صفحه کوکی ها"--> <!-- name="صفحه کوکی ها"-->
<!-- :to="{ name: 'admin-contents-details' , params : {details : 'cookies'} }"--> <!-- :to="{ name: 'admin-contents-details' , params : {details : 'cookies'} }"-->
@@ -251,31 +283,30 @@
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'faq' }, params: { details: 'faq' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="صفحه قوانین و مقررات" name="صفحه قوانین و مقررات"
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'rules' }, params: { details: 'rules' },
}" /> }"
/>
<CSidebarNavItem <CSidebarNavItem
name="صفحه نقشه سایت" name="صفحه نقشه سایت"
:to="{ :to="{
name: 'admin-contents-details', name: 'admin-contents-details',
params: { details: 'sitemap' }, params: { details: 'sitemap' },
}" /> }"
/>
</CSidebarNavDropdown> </CSidebarNavDropdown>
</CSidebarNav> </CSidebarNav>
<!-- sidebar content --> <!-- sidebar content -->
<CSidebarMinimizer <CSidebarMinimizer
class="d-md-down-none" class="d-md-down-none"
@click.native=" @click.native="$store.commit('admin/set', ['sidebarMinimize', !minimize])"
$store.commit('admin/set', [ />
'sidebarMinimize',
!minimize,
])
" />
</CSidebar> </CSidebar>
</template> </template>
@@ -294,11 +325,7 @@ export default {
"مشکلی هنگام خروج از سیسیتم بوجود امده لطفا دوباره تلاش کنید", "مشکلی هنگام خروج از سیسیتم بوجود امده لطفا دوباره تلاش کنید",
}; };
}, },
mixins: [ mixins: [unreadNewsMessages, unreadContactMessages, unreadMeetingReq],
unreadNewsMessages,
unreadContactMessages,
unreadMeetingReq,
],
computed: { computed: {
show() { show() {
return this.$store.state.admin.sidebarShow; return this.$store.state.admin.sidebarShow;
@@ -307,12 +334,10 @@ export default {
return this.$store.state.admin.sidebarMinimize; return this.$store.state.admin.sidebarMinimize;
}, },
unreadNewsMessages() { unreadNewsMessages() {
return this.$store.state.admin return this.$store.state.admin.unreadNewsMessagesCount;
.unreadNewsMessagesCount;
}, },
unreadContactMessages() { unreadContactMessages() {
return this.$store.state.admin return this.$store.state.admin.unreadContactMessagesCount;
.unreadContactMessagesCount;
}, },
unreadMeetingReq() { unreadMeetingReq() {
return this.$store.state.admin.unreadMeetingReqCount; return this.$store.state.admin.unreadMeetingReqCount;
@@ -321,13 +346,9 @@ export default {
methods: { methods: {
hasPermission(permission) { hasPermission(permission) {
if (this.$auth.loggedIn) { if (this.$auth.loggedIn) {
if ( if (this.$auth.user.permissions.includes("superAdmin")) {
this.$auth.user.permissions.includes("superAdmin")
) {
return true; return true;
} else if ( } else if (this.$auth.user.permissions.includes(permission)) {
this.$auth.user.permissions.includes(permission)
) {
return true; return true;
} else { } else {
return false; return false;
+16 -12
View File
@@ -3,7 +3,6 @@ const webpack = require("webpack");
const serverPort = 3756; const serverPort = 3756;
export default { export default {
// Global page headers: https://go.nuxtjs.dev/config-head // Global page headers: https://go.nuxtjs.dev/config-head
head: { head: {
title: "پورتال خبری استانداری", title: "پورتال خبری استانداری",
@@ -44,18 +43,27 @@ export default {
type: "text/css", type: "text/css",
href: "/js/flipBook/font-awesome.css", href: "/js/flipBook/font-awesome.css",
}, },
{ rel: 'stylesheet', {
href: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js' } rel: "stylesheet",
href: "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js",
},
], ],
script: [ script: [
{ src: "https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js" }, { src: "https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js" },
{ src: "https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js" }, {
src: "https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js",
},
{ src: "/js/flipBook/flipbook.min.js" }, { src: "/js/flipBook/flipbook.min.js" },
{ src: "/js/lightBox/simple-lightbox.min.js" }, { src: "/js/lightBox/simple-lightbox.min.js" },
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js', defer: true }, {
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery-flipbook/1.0.5/jquery.flipbook.min.js', defer: true } src: "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js",
defer: true,
},
{
src: "https://cdnjs.cloudflare.com/ajax/libs/jquery-flipbook/1.0.5/jquery.flipbook.min.js",
defer: true,
},
], ],
}, },
loading: "~/components/pageLoad.vue", loading: "~/components/pageLoad.vue",
@@ -68,7 +76,6 @@ export default {
"~/assets/scss/main.scss", "~/assets/scss/main.scss",
], ],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [ plugins: [
"@/plugins/element-ui", "@/plugins/element-ui",
@@ -85,10 +92,7 @@ export default {
], ],
// Auto import components: https://go.nuxtjs.dev/config-components // Auto import components: https://go.nuxtjs.dev/config-components
components: [ components: ["~/components/", { path: "~/components/admin/", prefix: "" }],
"~/components/",
{ path: "~/components/admin/", prefix: "" },
],
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [], buildModules: [],
+91 -53
View File
@@ -4,15 +4,15 @@
<CCardGroup> <CCardGroup>
<CCard class="p-4"> <CCard class="p-4">
<CCardBody> <CCardBody>
<CForm <CForm v-if="step === 1" @submit.prevent="doLogin">
v-if="step === 1"
@submit.prevent="doLogin">
<h1 class="text-muted text-center mb-5">پنل مدیریت</h1> <h1 class="text-muted text-center mb-5">پنل مدیریت</h1>
<CInput <CInput
:class="validation.username ? 'err' : null" :class="validation.username ? 'err' : null"
placeholder="شماره موبایل" placeholder="شماره موبایل"
:description="validation.username ? validation.username.msg : null" :description="
validation.username ? validation.username.msg : null
"
autocomplete="username email" autocomplete="username email"
v-model="phone" v-model="phone"
> >
@@ -54,23 +54,22 @@
<CInputCheckbox label="مرا به خاطر بسپار" @update:checked="val => login.remember_me = val"/> --> <CInputCheckbox label="مرا به خاطر بسپار" @update:checked="val => login.remember_me = val"/> -->
<CRow> <CRow>
<CCol col="12" class="text-right mt-2"> <CCol col="12" class="text-right mt-2">
<CButton color="primary" @click="send_number" class="px-4">ارسال کد</CButton> <CButton color="primary" @click="send_number" class="px-4"
>ارسال کد</CButton
>
</CCol> </CCol>
</CRow> </CRow>
<!-- <p class="text-muted mt-3" style="font-size: 11px;">*درصورتی که گزینه "مرا به خاطر بسپار" را فعال نکنید بعد از 1 ساعت باید دوباره وارد سیستم شوید.</p> --> <!-- <p class="text-muted mt-3" style="font-size: 11px;">*درصورتی که گزینه "مرا به خاطر بسپار" را فعال نکنید بعد از 1 ساعت باید دوباره وارد سیستم شوید.</p> -->
</CForm> </CForm>
<CForm v-if="step === 2" @submit.prevent="doLogin">
<CForm
v-if="step === 2"
@submit.prevent="doLogin">
<h1 class="text-muted text-center mb-5">پنل مدیریت</h1> <h1 class="text-muted text-center mb-5">پنل مدیریت</h1>
<CInput <CInput
:class="validation.username ? 'err' : null" :class="validation.username ? 'err' : null"
placeholder="کد ورود را وارد کنید" placeholder="کد ورود را وارد کنید"
:description="validation.username ? validation.username.msg : null" :description="
validation.username ? validation.username.msg : null
"
autocomplete="username email" autocomplete="username email"
v-model="otp" v-model="otp"
> >
@@ -81,13 +80,12 @@
<CRow> <CRow>
<CCol col="12" class="text-right mt-2"> <CCol col="12" class="text-right mt-2">
<CButton color="primary" type="submit" class="px-4">ارسال کد</CButton> <CButton color="primary" type="submit" class="px-4"
>ورود</CButton
>
</CCol> </CCol>
</CRow> </CRow>
</CForm> </CForm>
</CCardBody> </CCardBody>
</CCard> </CCard>
</CCardGroup> </CCardGroup>
@@ -96,71 +94,111 @@
</template> </template>
<script> <script>
import { ref } from 'vue'; import { ref } from "vue";
export default { export default {
data() { data() {
return { return {
showPass: false, showPass: false,
step: 1, step: 1,
phone: '', phone: "",
otp: '', otp: "",
login: { login: {
username: '', username: "",
password: '', password: "",
remember_me: false remember_me: false,
}, },
validation: {} validation: {},
} };
}, },
computed: { computed: {
passwordState() { passwordState() {
return this.showPass ? "text" : "password" return this.showPass ? "text" : "password";
} },
}, },
methods: { methods: {
async send_number() { async send_number() {
console.log(this.phone) if (!this.phone) {
const phoneNumber = this.phone this.$message({
const send_request = await fetch('/api/auth/otp', { type: "warning",
method: 'POST', message: "شماره تماس را وارد کنید !",
});
return;
}
try {
const phoneNumber = this.phone;
const send_request = await fetch("/api/auth/otp", {
method: "POST",
headers: { headers: {
'Accept' : 'application/json', Accept: "application/json",
'content-type' : 'application/json' "content-type": "application/json",
}, },
body: JSON.stringify({phone: phoneNumber}) body: JSON.stringify({ phone: phoneNumber }),
});
}) if (send_request.status === 429 || send_request.status === 406) {
//if (send_request.status === 200) { this.$message({
this.step = 2 type: "warning",
//} message: "شما دسترسی ورود ندارید !",
});
return;
}
if (send_request.status === 200 || send_request.status === 201) {
this.$message({
type: "success",
message: "کد ورود ارسال شد",
});
this.step = 2;
return;
} else {
this.$message({
type: "warning",
message: "مشکل در برقرای ارتباط",
});
}
} catch (error) {
console.log("err", error);
this.$message({
type: "warning",
message: "خطای ناشناخته",
});
return;
}
}, },
doLogin() { doLogin() {
this.validation = {} this.validation = {};
this.$auth.loginWith('local', { this.$auth
.loginWith("local", {
data: { data: {
phone: this.phone, phone: this.phone,
code: this.otp code: this.otp,
} },
}) })
.then(response => { .then((response) => {
window.location.replace(window.location.origin + "/admin" ) window.location.replace(window.location.origin + "/admin");
}) })
.catch(err => { .catch((err) => {
if (err.response.status === 422) this.validation = err.response.data.validation if (err.response.status === 422)
this.validation = err.response.data.validation;
if (err.response.status === 403) { if (err.response.status === 403) {
this.$message({ this.$message({
type: 'warning', type: "warning",
message: err.response.data.message message: err.response.data.message,
}) });
} else console.log(err.response.data) } else {
}) this.$message({
type: "warning",
message: err?.response?.data?.validation?.code?.msg,
});
console.log(err.response.data.validation.code.msg);
} }
});
}, },
layout: 'admin-auth', },
layout: "admin-auth",
} };
</script> </script>
<style lang="scss"> <style lang="scss">
+245
View File
@@ -0,0 +1,245 @@
<template>
<div>
<CCard>
<CCardHeader>
<slot name="header">
<i class="fal fa-bars"></i>
<span>{{ list_title }}</span>
</slot>
<slot></slot>
</CCardHeader>
<CCardBody>
<el-table v-loading="loading" :data="sessions" style="width: 100%">
<el-table-column type="index" label="#"> </el-table-column>
<el-table-column label="نام کاربر">
<template slot-scope="scope">
<span class="title">
<el-popover
placement="top-end"
trigger="hover"
:content="scope.row.title"
>
</el-popover>
{{ scope.row?.user?.firstName + scope?.row?.user?.lastName }}
</span>
</template>
</el-table-column>
<el-table-column label="شماره موبایل">
<template slot-scope="scope">
<span class="title">
<el-popover
placement="top-end"
trigger="hover"
:content="scope.row.title"
>
</el-popover>
{{ scope.row?.user?.mobileNumber }}
</span>
</template>
</el-table-column>
<el-table-column label="آی پی">
<template slot-scope="scope">
<span class="title">
<el-popover
placement="top-end"
trigger="hover"
:content="scope.row.title"
>
</el-popover>
{{ scope.row?.ip }}
</span>
</template>
</el-table-column>
<el-table-column label="تاریخ ورود" width="">
<template slot-scope="scope">
<span>{{ scope.row.LastLogin }}</span>
</template>
</el-table-column>
</el-table>
</CCardBody>
</CCard>
<CCard class="col">
<CRow alignHorizontal="center" style="padding: 10px">
<el-pagination
:hide-on-single-page="true"
layout="prev, pager, next"
page-size="10"
@current-change="change_page"
:current-page.sync="elections.page"
:total="length"
>
</el-pagination>
</CRow>
</CCard>
</div>
</template>
<script>
import moment from "moment-jalaali";
export default {
data() {
return {
title: "لیست انتخابات",
list_title: "لیست",
elections: null,
search: {},
parent: null,
loading: false,
sessions: [],
length: null,
page: 1,
};
},
computed: {
pageQuery() {
return this.$route.query.page;
},
},
watch: {
pageQuery(newPage, oldPage) {
this.$nuxt.refresh();
},
},
mounted() {
this.getData();
},
methods: {
jDate(date) {
return moment(date).format("jYYYY/jMM/jDD");
},
async change_page(value) {
this.page = value;
this.getData();
},
async getData() {
try {
const response = await this.$axios.get(
`/api/admin/logs?page=${this.page}&limit=10`
);
// const data = await response.json(); // if you want to parse JSON response
console.log(response, "res");
this.sessions = response?.data?.logs;
this.length = response?.data?.totalLogs;
} catch (error) {
console.error("Failed to fetch data:", error);
}
},
deletePoll(id) {
this.$confirm("انتخابات حذف شود؟", "اخطار", {
confirmButtonText: "بله",
cancelButtonText: "لغو",
type: "warning",
})
.then(async () => {
this.$axios
.delete(`/api/admin/election/${id}`)
.then((res) => {
this.$message({
type: "success",
message: "انتخابات با موفقیت حذف شد",
});
this.elections.docs = this.elections.docs.filter(
(item) => item._id !== id
);
})
.catch((err) => {
if (err.response.status === 401) {
return this.$message({
type: "error",
message: "لطفا دوباره وارد سیستم شوید.",
});
}
if (err.response.status === 403) {
return this.$message({
type: "error",
message: err.response.data.message,
});
}
if (err.response.status === 422) {
return this.$message({
type: "error",
message: err.response.data.message,
});
}
console.log(err.response.data);
});
})
.catch(() => {
this.$message({
type: "warning",
message: "عملیات لغو شد",
});
});
},
handleCurrentChange(page) {
this.handleSearch(page);
},
handleSearch(page) {
this.loading = true;
const data = {
term: this.search.term,
catId: this.search.catId,
showInHome: this.search.showInHome,
};
this.$axios
.post(`/api/admin/election/search?page=${page}`, data, this.axiosConfig)
.then((result) => {
this.elections = result.data;
this.loading = false;
})
.catch((err) => {
this.loading = false;
if (err.response.status === 401) {
return this.$message({
type: "error",
message: "لطفا دوباره وارد سیستم شوید.",
});
}
if (err.response.status === 422)
this.validation = err.response.data.validation;
else console.log(err.response.data);
});
},
},
head() {
return {
title: this.title,
};
},
layout: "admin",
async asyncData({ $axios, query, error }) {
try {
const requests = [
$axios.get(`/api/admin/election?page=${query.page}`),
$axios.get("/api/admin/category/getParent"),
];
const fetch = await Promise.all(requests);
let [elections, parents] = fetch;
return {
elections: elections.data,
parents: parents.data,
};
} catch (e) {
if (e?.response?.status === 401)
error({
status: 401,
message: "شما اجازه دسترسی به این صفحه را ندارید",
});
else
error({
status: 500,
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
});
}
},
};
</script>
+42 -35
View File
@@ -1,37 +1,41 @@
const jwt = require('jsonwebtoken') const jwt = require("jsonwebtoken");
const User = require('./models/User'); const User = require("./models/User");
const {res500} = require('./plugins/controllersHelperFunctions'); const { res500 } = require("./plugins/controllersHelperFunctions");
const Category = require('./models/Category'); const Category = require("./models/Category");
const Election = require('./models/Election'); const Election = require("./models/Election");
const authentication = { const authentication = {
// secret for generating jwt token // secret for generating jwt token
secretKey: 'kyQa8pFI5BJnj7LCVPlSfoATTSZuS5DMSjgBPxQo2zkcdKnxKCPzWs1DEBgMfnXFsjgT0YWgqn8HgLLcmdIgSR6fSQpy6vchmY3kUSD564J', secretKey:
"kyQa8pFI5BJnj7LCVPlSfoATTSZuS5DMSjgBPxQo2zkcdKnxKCPzWs1DEBgMfnXFsjgT0YWgqn8HgLLcmdIgSR6fSQpy6vchmY3kUSD564J",
// check if just logged in (admin-or-user) (middleware) // check if just logged in (admin-or-user) (middleware)
isLoggedIn: async function (req, res, next) { isLoggedIn: async function (req, res, next) {
try { try {
const token = req.headers.authorization?.replace(/^Bearer\s/, ''); const token = req.headers.authorization?.replace(/^Bearer\s/, "");
if (token) { if (token) {
// check if token is not destroyed // check if token is not destroyed
var user = await User.findOne({ token: token }); var user = await User.findOne({ token: token });
if (!user) { if (!user) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
if (!user.registration_done) { if (!user.registration_done) {
return res500(res, 'user is disable please contact to support'); return res500(res, "user is disable please contact to support");
} }
//verifies secret and checks if the token is expired //verifies secret and checks if the token is expired
try { try {
var checkToken = await jwt.verify(user.token.replace(/^Bearer\s/, ''), authentication.secretKey); var checkToken = await jwt.verify(
user.token.replace(/^Bearer\s/, ""),
authentication.secretKey
);
if (!checkToken) { if (!checkToken) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
} catch (error) { } catch (error) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
req.user = { req.user = {
@@ -40,12 +44,12 @@ const authentication = {
portals: user.portals, portals: user.portals,
permissions: user.permissions, permissions: user.permissions,
specialPermissions: user.specialPermissions, specialPermissions: user.specialPermissions,
private: user.private private: user.private,
}; };
return next(); return next();
} else { } else {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
} catch (error) { } catch (error) {
return res500(res, error.message); return res500(res, error.message);
@@ -59,16 +63,16 @@ const authentication = {
if (req.user) { if (req.user) {
const scope = req.user.scope; const scope = req.user.scope;
if (!scope.includes('admin')) { if (!scope.includes("admin")) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
return next() return next();
} else { } else {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
} catch (error) { } catch (error) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
}, },
// check if user has permission (middleware) // check if user has permission (middleware)
@@ -76,18 +80,18 @@ const authentication = {
return (req, res, next) => { return (req, res, next) => {
if (req.user && req.user.permissions) { if (req.user && req.user.permissions) {
const permissions = req.user.permissions; const permissions = req.user.permissions;
if (permissions.includes('superAdmin')) { if (permissions.includes("superAdmin")) {
return next(); return next();
} }
if (!permissions.includes(permission)) { if (!permissions.includes(permission)) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} else { } else {
return next(); return next();
} }
} else { } else {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
}
} }
};
}, },
// hasSpecPermission: () => { // hasSpecPermission: () => {
// return async (req, res, next) => { // return async (req, res, next) => {
@@ -116,32 +120,35 @@ const authentication = {
// } // }
// } // }
// }, // },
hasSubPermission: () => { hasSubPermission: () => {
return (req, res, next, value) => { return (req, res, next, value) => {
if (req.user && req.user.permissions) { if (req.user && req.user.permissions) {
var permissions = req.user.permissions; var permissions = req.user.permissions;
if (permissions.includes('superAdmin')) { if (permissions.includes("superAdmin")) {
return next(); return next();
} }
if (!permissions.some(item => new RegExp(value, 'i').test(item))) { if (!permissions.some((item) => new RegExp(value, "i").test(item))) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} else { } else {
return next(); return next();
} }
} else { } else {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
}
} }
};
}, },
isVoter: async function (req, res, next) { isVoter: async function (req, res, next) {
try { try {
const token = req.headers.authorization?.replace(/^Bearer\s/, ''); const token = req.headers.authorization?.replace(/^Bearer\s/, "");
if (token) { if (token) {
// check if token is not destroyed // check if token is not destroyed
const user = await Election.findOne({'voters': {$elemMatch: {_id: token}}}); const user = await Election.findOne({
voters: { $elemMatch: { _id: token } },
});
if (!user) { if (!user) {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
const voter = user.voters.id(token); const voter = user.voters.id(token);
@@ -150,17 +157,17 @@ const authentication = {
_id: voter._id, _id: voter._id,
username: voter.username, username: voter.username,
password: voter.password, password: voter.password,
voted: voter.voted voted: voter.voted,
}; };
return next(); return next();
} else { } else {
return res.status(401).json({message: 'unauthorized'}); return res.status(401).json({ message: "unauthorized" });
} }
} catch (error) { } catch (error) {
return res500(res, error.message); return res500(res, error.message);
} }
}, },
} };
module.exports = authentication module.exports = authentication;
+1 -1
View File
@@ -34,7 +34,7 @@ module.exports.getAdminLoginLogs = [
try { try {
const { const {
page = 1, page = 1,
limit = 1000, limit = 10,
sort = "desc", sort = "desc",
fromDate, fromDate,
toDate, toDate,
+25 -23
View File
@@ -1,38 +1,42 @@
const mongoose = require('mongoose'); const mongoose = require("mongoose");
function autoPopulateSubs(next) { function autoPopulateSubs(next) {
this.populate({ this.populate({
path: 'childs', path: "childs",
select: 'title childs navIndex url modelType treeCat parent defaultPageType', select:
"title childs navIndex url modelType treeCat parent defaultPageType",
options: { options: {
sort : 'navIndex' sort: "navIndex",
} },
// sort: {navIndex: -1}, // sort: {navIndex: -1},
}); });
next(); next();
} }
function file(file) { function file(file) {
return '/uploads/files/terms/' + file return "/uploads/files/terms/" + file;
} }
function image(img) { function image(img) {
if (img) return '/uploads/images/category/' + img if (img) return "/uploads/images/category/" + img;
else return '/img/no-cover.jpg' else return "/img/no-cover.jpg";
} }
const CategoryTermsFile = mongoose.Schema({ const CategoryTermsFile = mongoose.Schema({
file: { type: String, get: file }, file: { type: String, get: file },
title: String title: String,
}) });
const CategorySchema = mongoose.Schema({ const CategorySchema = mongoose.Schema({
title: String, title: String,
parent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null}, parent: {
childs: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}], type: mongoose.Schema.Types.ObjectId,
treeCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}], ref: "Category",
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'}, default: null,
},
childs: [{ type: mongoose.Schema.Types.ObjectId, ref: "Category" }],
treeCat: [{ type: mongoose.Schema.Types.ObjectId, ref: "Category" }],
rootParent: { type: mongoose.Schema.Types.ObjectId, ref: "Category" },
priority: { type: Number, default: 0 }, priority: { type: Number, default: 0 },
showInMenu: Boolean, showInMenu: Boolean,
navIndex: { type: Number, default: null }, navIndex: { type: Number, default: null },
@@ -43,8 +47,8 @@ const CategorySchema = mongoose.Schema({
level: { type: Number, default: 1 }, level: { type: Number, default: 1 },
siteMap: { type: Boolean, default: true }, siteMap: { type: Boolean, default: true },
modelType: String, modelType: String,
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, _creator: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, _updatedBy: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
haveNews: { type: Boolean, default: false }, haveNews: { type: Boolean, default: false },
///// for client ///// for client
hasNewsTab: { type: Boolean, default: true }, hasNewsTab: { type: Boolean, default: true },
@@ -56,7 +60,7 @@ const CategorySchema = mongoose.Schema({
hasSpecNewsTab: { type: Boolean, default: true }, hasSpecNewsTab: { type: Boolean, default: true },
hasNazarTab: { type: Boolean, default: true }, hasNazarTab: { type: Boolean, default: true },
hasNewsFileTab: { type: Boolean, default: true }, hasNewsFileTab: { type: Boolean, default: true },
defaultPageType: {type: String, default: 'news'}, defaultPageType: { type: String, default: "news" },
/** page */ /** page */
showInFooter: { type: Number, enum: [0, 1, 2, 3], default: 0 }, showInFooter: { type: Number, enum: [0, 1, 2, 3], default: 0 },
url: { type: String, default: null }, url: { type: String, default: null },
@@ -65,13 +69,11 @@ const CategorySchema = mongoose.Schema({
hasManagerInfo: { type: Boolean, default: true }, hasManagerInfo: { type: Boolean, default: true },
managerCover: { type: String, get: image }, managerCover: { type: String, get: image },
managerName: String, managerName: String,
managerDescription: String managerDescription: String,
}); });
CategorySchema.index({ parent: 1, childs: 1 }); CategorySchema.index({ parent: 1, childs: 1 });
CategorySchema CategorySchema.pre("findOne", autoPopulateSubs).pre("find", autoPopulateSubs);
.pre('findOne', autoPopulateSubs)
.pre('find', autoPopulateSubs);
module.exports = mongoose.model('Category', CategorySchema); module.exports = mongoose.model("Category", CategorySchema);
+1 -1
View File
@@ -28,7 +28,6 @@ module.exports.sms = async (phoneNumber, message) => {
SendDateTime: "", SendDateTime: "",
CanContinueInCaseOfError: "false", CanContinueInCaseOfError: "false",
}; };
const response = await axios.post( const response = await axios.post(
`http://RestfulSms.com/api/MessageSend`, `http://RestfulSms.com/api/MessageSend`,
data, data,
@@ -39,6 +38,7 @@ module.exports.sms = async (phoneNumber, message) => {
}, },
} }
); );
return response.data; return response.data;
} catch (e) { } catch (e) {
console.log(e); console.log(e);