transfer project in github
This commit is contained in:
@@ -0,0 +1,609 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-customers'}">برگشت به صفحه قبل</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<template v-if="$route.params.profile !== 'new'">
|
||||
<h4>مشخصات مشتری</h4>
|
||||
<el-divider/>
|
||||
</template>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="نام"
|
||||
disabled
|
||||
:value="customer.first_name"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="نام خانوادگی"
|
||||
disabled
|
||||
:value="customer.last_name"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="کد مشتری"
|
||||
disabled
|
||||
:value="customer.business_code"
|
||||
/>
|
||||
<p class="form-err" v-if="validation.username">{{ validation.username.msg }}</p>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="تلفن همراه"
|
||||
disabled
|
||||
:value="customer.mobile_number"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="ایمیل"
|
||||
disabled
|
||||
:value="customer.email"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="کد ملی"
|
||||
disabled
|
||||
:value="customer.national_code"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="شغل"
|
||||
disabled
|
||||
:value="customer.job"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="تاریخ تولد"
|
||||
disabled
|
||||
:value="jDateOfCustomer(customer.birth_date)"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="تاریخ ازدواج"
|
||||
disabled
|
||||
:value="jDateOfCustomer(customer.marriage_date)"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="امتیاز"
|
||||
disabled
|
||||
:value="customer.score"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
label="موجودی کیف پول"
|
||||
disabled
|
||||
:value="customer.bagAmount + ' ریال'"
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h4>کد های تخفیف مشتری</h4>
|
||||
<el-divider></el-divider>
|
||||
<el-table
|
||||
:data="customer.discount_codes"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="discount_code"
|
||||
label="کد"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="درصد تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.discount_amount + '%' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="استفاده شده"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.used_by.includes(customer._id)">بله</span>
|
||||
<span v-else>خیر</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="province"
|
||||
label="تاریخ انقضا"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDateDiscount(scope.row.discount_expire_date) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h4>آدرس های مشتری</h4>
|
||||
<el-divider></el-divider>
|
||||
<el-table
|
||||
:data="customer.addresses"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="title"
|
||||
label="عنوان"
|
||||
width="100">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="province"
|
||||
label="استان"
|
||||
width="100">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="city"
|
||||
label="شهر"
|
||||
width="100">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="address"
|
||||
label="آدرس"
|
||||
width="600">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="200"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" @click="deleteAddress(scope.row._id)" :key="scope.row._id + Math.random()">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton
|
||||
variant="outline"
|
||||
title="بروزرسانی"
|
||||
color="success"
|
||||
:key="scope.row._id"
|
||||
@click="openDialog(scope.row)">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h4>لیست تراکنش ها</h4>
|
||||
<el-divider></el-divider>
|
||||
<el-table
|
||||
:data="payments.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="نوع تراکنش"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
type="success"
|
||||
effect="dark">
|
||||
<span>{{
|
||||
scope.row.action === 'increaseBag' ? 'افزایش کیف پول' : scope.row.action === 'decreaseBag' ? 'کاهش کیف پول' : 'پرداخت اینترنتی'
|
||||
}}
|
||||
</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="وضعیت پرداخت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="scope.row.status === 'paid' ? 'success' : 'danger' "
|
||||
effect="dark">
|
||||
<span>{{ scope.row.status === 'paid' ? 'پرداخت موفق' : 'پرداخت ناموفق'}}</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="مبلغ"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.cost.toLocaleString() + ' ریال' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ و ساعت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDate(scope.row.created_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="payments.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="payments.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="payments.page" :total="payments.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h4>لاگ امتیازها</h4>
|
||||
<el-divider></el-divider>
|
||||
<el-table
|
||||
:data="customer.scoreLogs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="وضعیت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="scope.row.action === 'decrease'? 'danger' : 'success'"
|
||||
effect="dark">
|
||||
<span>{{scope.row.action === 'decrease' ? 'کاهش امتیاز' : 'افزایش امتیاز' }}</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="برای"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ forWhat(scope.row.forWhat)}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="امتیاز"
|
||||
prop="score"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ و ساعت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDate(scope.row.created_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<el-dialog
|
||||
title="آدرس"
|
||||
:visible.sync="dialogVisible"
|
||||
width="50%">
|
||||
<CInput
|
||||
label="عنوان"
|
||||
:class="validation.title ? 'err' : null"
|
||||
:description="validation.title ? validation.title.msg : null"
|
||||
v-model="address.title"/>
|
||||
<CInput
|
||||
label="استان"
|
||||
:class="validation.province ? 'err' : null"
|
||||
:disabled="true"
|
||||
:description="validation.province ? validation.province.msg : null"
|
||||
v-model="address.province"/>
|
||||
<CInput
|
||||
label="شهر"
|
||||
:class="validation.city ? 'err' : null"
|
||||
:disabled="true"
|
||||
:description="validation.city ? validation.city.msg : null"
|
||||
v-model="address.city"/>
|
||||
<CInput
|
||||
label="آدرس"
|
||||
:class="validation.address ? 'err' : null"
|
||||
:description="validation.address ? validation.address.msg : null"
|
||||
v-model="address.address"/>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="success" @click="updateAddress">بروزرسانی</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from "moment-jalaali"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'مشاهده پروفایل مشتری',
|
||||
customer: null,
|
||||
payments : null,
|
||||
dialogVisible: false,
|
||||
validation: {},
|
||||
address: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
forWhat(status) {
|
||||
switch (status) {
|
||||
case 'birthDate':
|
||||
return 'تولد'
|
||||
case 'marriageDate':
|
||||
return 'سالگرد ازدواج'
|
||||
case 'buy':
|
||||
return 'خرید'
|
||||
case 'register':
|
||||
return 'ثبت نام'
|
||||
case 'invite':
|
||||
return 'دعوت دوستان'
|
||||
case 'emailVerify':
|
||||
return 'تایید ایمیل'
|
||||
default :
|
||||
return 'نامشخص'
|
||||
}
|
||||
},
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-customers-profile",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
openDialog(address) {
|
||||
this.address = address
|
||||
this.dialogVisible = true
|
||||
},
|
||||
updateAddress() {
|
||||
this.validation = {}
|
||||
this.$axios.put(`/api/admin/address/${this.address._id}`, this.address)
|
||||
.then(res => {
|
||||
this.dialogVisible = false;
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'آدرس با موفقیت ثبت شد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err.response.data)
|
||||
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 === 500) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "مشکلی در ارسال درخواست پیش آمده",
|
||||
});
|
||||
}
|
||||
if (err.response.status === 422) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'پارامترها را بررسی کنید'
|
||||
})
|
||||
this.validation = err.response.data.validation;
|
||||
} else console.log(err.response.data);
|
||||
})
|
||||
},
|
||||
deleteAddress(id) {
|
||||
this.$confirm("آدرس حذف شود؟", "اخطار", {
|
||||
confirmButtonText: "بله",
|
||||
cancelButtonText: "لغو",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
this.validation = {}
|
||||
this.$axios.delete(`/api/admin/address/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'آدرس با موفقیت حذف شد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.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 === 404) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: err.response.data.message,
|
||||
});
|
||||
}
|
||||
if (err.response.status === 500) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "مشکلی در ارسال درخواست پیش آمده",
|
||||
});
|
||||
}
|
||||
if (err.response.status === 422) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'پارامترها را بررسی کنید'
|
||||
})
|
||||
this.validation = err.response.data.validation;
|
||||
} else console.log(err.response.data);
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: "warning",
|
||||
message: "عملیات لغو شد",
|
||||
});
|
||||
});
|
||||
},
|
||||
imagePreview(e) {
|
||||
this.customer.profile_pic = URL.createObjectURL(e.target.files[0])
|
||||
},
|
||||
jDate(date) {
|
||||
return moment(date).format('jYYYY/jMM/jDD HH:MM')
|
||||
},
|
||||
jDateOfCustomer(date) {
|
||||
if (date){
|
||||
return moment(date).format('jYYYY/jMM/jDD')
|
||||
}
|
||||
},
|
||||
jDateDiscount(date) {
|
||||
return moment(date , 'X').format('jYYYY/jMM/jDD')
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append("first_name", this.customer.first_name)
|
||||
data.append("last_name", this.customer.last_name)
|
||||
data.append("mobile_number", this.customer.mobile_number)
|
||||
data.append("email", this.customer.email)
|
||||
data.append("username", this.customer.username)
|
||||
data.append("permissions", JSON.stringify(this.customer.permissions))
|
||||
data.append("password", this.customer.password)
|
||||
data.append("password_confirmation", this.customer.password_confirmation)
|
||||
if (this.$refs.profile_pic.files[0]) data.append("profile_pic", this.$refs.profile_pic.files[0])
|
||||
|
||||
this.$axios.put(`/api/admin/admin/${this.customer._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, query , error}) {
|
||||
try {
|
||||
const customer = await $axios.get(`/api/admin/user/${params.profile}`)
|
||||
const payments = await $axios.get(`/api/admin/payments/${params.profile}?page=${query.page || 1}`)
|
||||
return {
|
||||
customer: customer.data,
|
||||
payments: payments.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<a :href="`/api/public/users/exportExel/${$auth.user._id}`" target="_blank" class="mr-auto">
|
||||
<CButton size="sm" color="success">خروجی اکسل</CButton>
|
||||
</a>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="customers.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="first_name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="last_name"
|
||||
label="نام خانوادگی"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="mobile_number"
|
||||
label="شماره موبایل"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="business_code"
|
||||
label="کد مشتری"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column
|
||||
prop="score"
|
||||
label="score"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="مشاهده"
|
||||
width="70"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="success" variant="outline" :key="scope.row._id"
|
||||
:to="{name: 'admin-branch-customers-profile',params: {profile: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="customers.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="customers.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="customers.page" :total="customers.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست مشتریان',
|
||||
list_title: 'لیست',
|
||||
customers: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-customers",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
deleteUser(id) {
|
||||
this.$confirm('کاربر حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/admin/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'کاربر با موفقیت حذف شد'
|
||||
})
|
||||
this.customers.docs = this.customers.docs.filter(item => item._id !== id)
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response.status === 401) {
|
||||
return this.$message({
|
||||
type: 'error',
|
||||
message: 'لطفا دوباره وارد سیستم شوید.'
|
||||
})
|
||||
}
|
||||
console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
},
|
||||
async createExel(){
|
||||
try {
|
||||
const createExel = await this.$axios.$get(`/api/admin/users/exportExel`);
|
||||
|
||||
console.log(createExel)
|
||||
}catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'مشکلی در گرفتن اطلاعات بوجود آمده است'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios,query, error, params}) {
|
||||
try {
|
||||
const customers = await $axios.get(`/api/admin/users/${params.branch}?page=${query.page || 1}`)
|
||||
return {
|
||||
customers: customers.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<!-- <CButton size="sm" color="success" :to="{name: 'admin-discounts-discount',params:{profile: 'new'}}" class="mr-auto">افزودن</CButton>-->
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<h2>افزودن کد تخفیف</h2>
|
||||
<el-divider></el-divider>
|
||||
<el-button-group>
|
||||
<el-button :type="newDiscountIsPublic ? 'info' : 'primary'" @click="newDiscountIsPublic = false" icon="el-icon-arrow-left">کد تخفیف اختصاصی</el-button>
|
||||
<el-button :type="newDiscountIsPublic ? 'primary' : 'info'" @click="newDiscountIsPublic = true" icon="el-icon-arrow-left">کد تخفیف عمومی</el-button>
|
||||
</el-button-group>
|
||||
<br>
|
||||
<el-select
|
||||
v-if="!newDiscountIsPublic"
|
||||
v-model="discount_user_id"
|
||||
filterable
|
||||
style="width: 300px;margin-top: 20px;margin-bottom: 10px;">
|
||||
<el-option
|
||||
v-for="item in users"
|
||||
:key="item._id"
|
||||
:value="item._id"
|
||||
:label="item.business_code + ' ' + '(' + item.first_name + ' ' + item.last_name + ')'"/>
|
||||
</el-select>
|
||||
<p class="text-danger" v-if="validation.discount_user_id">{{ validation.discount_user_id.msg }}</p>
|
||||
|
||||
<div v-if="newDiscountIsPublic" style="margin-top: 20px;margin-bottom: 10px;">
|
||||
<el-switch
|
||||
style="direction: ltr;margin-bottom: 20px;"
|
||||
v-model="publicDiscountIsAuto"
|
||||
active-text="ایجاد کد تخفیف توسط سیستم"
|
||||
inactive-text="وارد کردن کد دستی">
|
||||
</el-switch>
|
||||
|
||||
<el-input v-model="customDiscountCode" v-if="!publicDiscountIsAuto" placeholder="کدتخفیف دستی را وارد کنید" style="width: 300px;display: block;"></el-input>
|
||||
<p class="text-danger" v-if="validation.customDiscountCode">{{ validation.customDiscountCode.msg }}</p>
|
||||
</div>
|
||||
|
||||
<el-input v-model="discount_amount" placeholder="درصد تخفیف را وارد کنید" style="display: block;width: 300px;margin-bottom: 10px;"></el-input>
|
||||
<p class="text-danger" v-if="validation.discount_amount">{{ validation.discount_amount.msg }}</p>
|
||||
|
||||
<date-picker
|
||||
v-model="discount_expire_date"
|
||||
placeholder="تاریخ انقضای کد را مشخص کنید"
|
||||
format="X"
|
||||
displayFormat="jYYYY/jMM/jDD"
|
||||
style="display: block;width: 300px!important;margin-bottom: 10px;"/>
|
||||
<p class="text-danger" v-if="validation.discount_expire_date">{{ validation.discount_expire_date.msg }}</p>
|
||||
|
||||
<el-select
|
||||
v-model="menuTypeId"
|
||||
filterable
|
||||
placeholder="منو را انتخاب کنید"
|
||||
style="width: 300px;margin-bottom: 20px;">
|
||||
<el-option
|
||||
v-for="item in menuTypes"
|
||||
:key="item._id"
|
||||
:value="item._id"
|
||||
:label="item.name"/>
|
||||
</el-select>
|
||||
<p class="text-danger" v-if="validation.menuTypeId">{{ validation.menuTypeId.msg }}</p>
|
||||
<br>
|
||||
<el-button type="success" @click="addDiscount">ایجاد کد تخفیف</el-button>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="discounts.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="discount_code"
|
||||
label="کد تخفیف"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="درصد تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span class="text-success">{{ scope.row.discount_amount + '%' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ انقضا"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDate(scope.row.discount_expire_date) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="در دسترس برای"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.isPublic" class="text-success">برای همه</span>
|
||||
<span v-else>{{ scope.row.discount_user_id.first_name + ' ' + scope.row.discount_user_id.last_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="حذف"
|
||||
width="75"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="deleteUser(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="discounts.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="discounts.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="discounts.page" :total="discounts.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment-jalaali'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست کدهای تخفیف',
|
||||
list_title: 'لیست',
|
||||
// base data
|
||||
discounts: null,
|
||||
users: null,
|
||||
menuTypes: null,
|
||||
// discount details
|
||||
discount_user_id: '',
|
||||
discount_expire_date: '',
|
||||
menuTypeId: '',
|
||||
discount_amount: '',
|
||||
customDiscountCode: '',
|
||||
newDiscountIsPublic: true,
|
||||
publicDiscountIsAuto: true,
|
||||
loading: false,
|
||||
// validation
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
},
|
||||
newDiscountIsPublic(newVal, oldVal) {
|
||||
this.validation = {}
|
||||
},
|
||||
publicDiscountIsAuto(newVal, oldVal) {
|
||||
this.validation = {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-discounts",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
addDiscount() {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'Loading',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
this.validation = {}
|
||||
const data = {
|
||||
discount_user_id: this.discount_user_id,
|
||||
discount_expire_date: this.discount_expire_date,
|
||||
discount_amount: this.discount_amount,
|
||||
menuTypeId: this.menuTypeId,
|
||||
customDiscountCode: this.customDiscountCode,
|
||||
newDiscountIsPublic: this.newDiscountIsPublic,
|
||||
publicDiscountIsAuto: this.publicDiscountIsAuto,
|
||||
branchId: this.$route.params.branch
|
||||
}
|
||||
this.$axios.post('/api/admin/discountCode', data)
|
||||
.then(res => {
|
||||
loading.close()
|
||||
this.$alert('', 'موفق', {
|
||||
type: 'success',
|
||||
message: `کد تخفیف: ${res.data.discount_code}`
|
||||
})
|
||||
this.discount_user_id = ''
|
||||
this.discount_expire_date = ''
|
||||
this.discount_amount = ''
|
||||
this.menuTypeId = ''
|
||||
this.customDiscountCode = ''
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
loading.close()
|
||||
if (err.response.status === 422) return this.validation = err.response.data.validation
|
||||
else if (err.response.status === 500) error({
|
||||
status: 500,
|
||||
message: err.response.data.message,
|
||||
});
|
||||
else console.log(err)
|
||||
})
|
||||
},
|
||||
deleteUser(id) {
|
||||
this.$confirm('کد تخفیف حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/discountCode/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'کد تخفیف با موفقیت حذف شد'
|
||||
})
|
||||
this.discounts.docs = this.discounts.docs.filter(item => item._id !== id)
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response.status === 401) {
|
||||
return this.$message({
|
||||
type: 'error',
|
||||
message: 'لطفا دوباره وارد سیستم شوید.'
|
||||
})
|
||||
}
|
||||
console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
},
|
||||
jDate(date) {
|
||||
return moment(date, 'X').format('jYYYY/jMM/jDD')
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, query, error, params}) {
|
||||
try {
|
||||
const users = await $axios.get(`/api/admin/users/getAll/${params.branch}`)
|
||||
const menuTypes = await $axios.get(`/api/public/menuTypes/getAll/${params.branch}`)
|
||||
const discounts = await $axios.get(`/api/admin/discountCodes/${params.branch}?page=${query.page || 1}`)
|
||||
return {
|
||||
users: users.data,
|
||||
discounts: discounts.data,
|
||||
menuTypes: menuTypes.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.el-button:focus {
|
||||
outline-color: #39f !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-food-categories'}">برگشت به صفحه
|
||||
قبل</CButton>
|
||||
<CButton v-if="$route.params.category === 'new'" size="sm" color="success" class="mr-1" @click="post">افزودن</CButton>
|
||||
<CButton v-else size="sm" color="success" class="mr-1" @click="update">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.name ? 'err' : null"
|
||||
label="نام"
|
||||
:description="validation.name ? validation.name.msg : null"
|
||||
v-model="foodCategory.name"
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCol s="12">
|
||||
<span>نوع منو</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="foodCategory.type" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option v-for="item in menuTypes" :key="item._id" :value="item._id" :label="item.name"/>
|
||||
</el-select>
|
||||
<p v-if="validation.type" class="text-danger" style="margin-top: 5px;">{{ validation.type.msg }}</p>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCol s="12" class="mt-3">
|
||||
<span>ترتیب نمایش در منو</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="foodCategory.index" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option
|
||||
v-for="item in 1000"
|
||||
v-if="!foodCategories.filter(item2=>Number(item2.index) === item && item2.type._id === foodCategory.type).length"
|
||||
:key="item + 202"
|
||||
:value="item"
|
||||
:label="item"/>
|
||||
</el-select>
|
||||
<p v-if="validation.index" class="text-danger" style="margin-top: 5px;">{{ validation.index.msg }}</p>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CForm>
|
||||
<el-divider></el-divider>
|
||||
<h3>کاور</h3>
|
||||
<img :src="foodCategory.cover" style="width: 100%;max-width: 300px;" alt="">
|
||||
<input type="file" ref="cover" @change="preview">
|
||||
<p class="text-danger" v-if="validation.cover">{{ validation.cover.msg }}</p>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
|
||||
</CRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axiosUploadProcess from "@/mixins/axiosUploadProcess"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
foodCategories: null,
|
||||
foodCategory: null,
|
||||
menuTypes: null,
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
mixins: [axiosUploadProcess],
|
||||
computed: {
|
||||
title() {
|
||||
return this.$route.params.category === 'new' ? 'افزودن دسته بندی' : 'مشاهده دسته بندی'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
preview(event) {
|
||||
this.foodCategory.cover = URL.createObjectURL(event.target.files[0])
|
||||
},
|
||||
post() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('name', this.foodCategory.name)
|
||||
data.append('type', this.foodCategory.type)
|
||||
data.append('index', this.foodCategory.index)
|
||||
data.append('cover', this.$refs.cover.files[0])
|
||||
data.append('branchId', this.$route?.params?.branch)
|
||||
|
||||
this.$axios.post(`/api/admin/foodCategory`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'دسته بندی با موفقیت ایجاد شد.'
|
||||
})
|
||||
this.$refs.cover.value = null
|
||||
this.$router.push({name: 'admin-branch-food-categories'})
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('name', this.foodCategory.name)
|
||||
data.append('type', this.foodCategory.type)
|
||||
data.append('index', this.foodCategory.index)
|
||||
data.append('branchId', this.$route?.params?.branch)
|
||||
if (this.$refs.cover.files[0]) data.append('cover', this.$refs.cover.files[0])
|
||||
|
||||
this.$axios.put(`/api/admin/foodCategory/${this.foodCategory._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
this.$refs.cover.value = null
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, error}) {
|
||||
try {
|
||||
const foodCategories = await $axios.get(`/api/public/foodCategories/getAll/${params?.branch}`)
|
||||
const menuTypes = await $axios.get(`/api/admin/allMenuType/getAll/${params?.branch}`)
|
||||
if (params.category !== 'new') {
|
||||
const foodCategory = await $axios.get(`/api/public/foodCategory/${params.category}`)
|
||||
return {
|
||||
foodCategories: foodCategories.data,
|
||||
menuTypes: menuTypes.data,
|
||||
foodCategory: foodCategory.data
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
foodCategories: foodCategories.data,
|
||||
menuTypes: menuTypes.data,
|
||||
foodCategory: {
|
||||
name: '',
|
||||
type: '',
|
||||
cover: '',
|
||||
index: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" :to="{name: 'admin-branch-food-categories-category',params:{category: 'new'}}"
|
||||
class="mr-auto">افزودن</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="foodCategories.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="کاور"
|
||||
width="200">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.cover" style="width: 100%;" alt="">
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="type.name"
|
||||
label="نوع منو"
|
||||
:filters="filter"
|
||||
:filter-method="filterType"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="remove(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="success" variant="outline" :key="scope.row._id" :to="{name:
|
||||
'admin-branch-food-categories-category',params: {category: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="foodCategories.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="foodCategories.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="foodCategories.page" :total="foodCategories.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست دسته بندی غذاها',
|
||||
list_title: 'لیست',
|
||||
foodCategories: null,
|
||||
menuTypes: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
},
|
||||
filter(){
|
||||
const fill = []
|
||||
for (const item of this.menuTypes) {
|
||||
fill.push({
|
||||
text : item.name,
|
||||
value : item._id
|
||||
})
|
||||
}
|
||||
return fill
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-food-categories",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
filterType(value, row){
|
||||
return row.type._id === value;
|
||||
},
|
||||
remove(id) {
|
||||
this.$confirm('این مورد حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/foodCategory/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'دسته بندی با موفقیت حذف شد'
|
||||
})
|
||||
this.foodCategories.docs = this.foodCategories.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
|
||||
})
|
||||
} else console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios,query, error, params}) {
|
||||
try {
|
||||
const foodCategories = await $axios.get(`/api/admin/foodCategory/getAll/${params.branch}?page=${query.page ||
|
||||
1}`)
|
||||
const menuTypes = await $axios.get(`/api/admin/allMenuType/getAll/${params.branch}`)
|
||||
return {
|
||||
foodCategories: foodCategories.data,
|
||||
menuTypes: menuTypes.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,573 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-foods'}">برگشت به صفحه قبل</CButton>
|
||||
<CButton v-if="$route.params.food === 'new'" size="sm" color="success" class="mr-1" @click="post">افزودن</CButton>
|
||||
<CButton v-else size="sm" color="success" class="mr-1" @click="update">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="food.special" label="قرار گرفتن در منوی ویژه سرآشپز"/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="food.havePoint" label="افزودن امتیاز به مشتری برای خرید این محصول"/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="food.sale" label="این محصول به صورت عادی فروخته شود"/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="food.club" label="این محصول با امتیاز به فروش برسد"/>
|
||||
</CCol>
|
||||
<el-divider></el-divider>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
v-if="food.club"
|
||||
:class="validation.point ? 'err' : null"
|
||||
label="مقدار امتیاز برای خرید"
|
||||
:description="validation.point ? validation.point.msg : null"
|
||||
v-model="food.point"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.name ? 'err' : null"
|
||||
label="نام"
|
||||
:description="validation.name ? validation.name.msg : null"
|
||||
v-model="food.name"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.short_description ? 'err' : null"
|
||||
label="توضیحات کوتاه"
|
||||
placeholder="پرس ویژه (اختیاری)"
|
||||
:description="validation.short_description ? validation.short_description.msg : null"
|
||||
v-model="food.short_description"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.description ? 'err' : null"
|
||||
label="توضیحات"
|
||||
placeholder="مواد تشکیل دهنده (اختیاری)"
|
||||
:description="validation.description ? validation.description.msg : null"
|
||||
v-model="food.description"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.estimated_time ? 'err' : null"
|
||||
label="زمان آماده سازی (دقیقه)"
|
||||
placeholder="اختیاری"
|
||||
:description="validation.estimated_time ? validation.estimated_time.msg : null"
|
||||
v-model="food.estimated_time"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.stock ? 'err' : null"
|
||||
label="موجودی"
|
||||
:description="validation.stock ? validation.stock.msg : null"
|
||||
v-model="food.stock"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.price ? 'err' : null"
|
||||
label="قیمت (ريال)"
|
||||
:description="validation.price ? validation.price.msg : null"
|
||||
v-model="food.price"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.static_discount ? 'err' : null"
|
||||
label="تخفیف روز (درصد)"
|
||||
placeholder="اختیاری"
|
||||
:description="validation.static_discount ? validation.static_discount.msg : null"
|
||||
v-model="food.static_discount"
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCol s="12">
|
||||
<span>دسته بندی</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="food.category" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option v-for="item in foodCategories" :key="item._id" :value="item._id" :label="item.name"/>
|
||||
</el-select>
|
||||
<p v-if="validation.category" class="text-danger" style="margin-top: 5px;">{{ validation.category.msg }}</p>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCol s="12" class="mt-3">
|
||||
<span>ترتیب نمایش در منو</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="food.index" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option
|
||||
v-for="item in foods.length + 10"
|
||||
v-if="!foods.find(item2=>Number(item2.index) === item && item2.category === food.category)"
|
||||
:key="item + 202"
|
||||
:value="item"
|
||||
:label="item"/>
|
||||
</el-select>
|
||||
<p v-if="validation.index" class="text-danger" style="margin-top: 5px;">{{ validation.index.msg }}</p>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h3>تصویر: (اختیاری)</h3>
|
||||
<el-divider></el-divider>
|
||||
<img :src="food.image" alt="" style="width: 100%;max-width: 300px;display: block">
|
||||
<input type="file" ref="image" @change="imagePreview">
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol v-if="$route.params.food !== 'new'">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<div class="row mb-5">
|
||||
<div class="col-sm-2">
|
||||
<div class="callout">
|
||||
<small class="text-muted">تعداد کل رای ها</small><br>
|
||||
<strong class="h4">{{ food.ratings.length }}</strong>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-2">
|
||||
<div class="callout rate">
|
||||
<small class="text-muted">میانگین امتیاز ها</small><br>
|
||||
<strong class="h4">
|
||||
{{ food.rate }}
|
||||
</strong>
|
||||
<i class="fas fa-star"></i>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
</div><!--/.row-->
|
||||
<h3>نظرات مشتریان</h3>
|
||||
<el-divider></el-divider>
|
||||
<el-table
|
||||
:data="food.ratings.filter(item=>item.comment && item.comment.length)"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop=""
|
||||
label="نام"
|
||||
width="">
|
||||
<template slot-scope="scope" v-if="scope.row.user_id">
|
||||
{{ scope.row.user_id.first_name + ' ' + scope.row.user_id.last_name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDate(scope.row.cretated_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="امتیاز"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.rate }}</span>
|
||||
<i class="fas fa-star"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="نظر"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-popover v-if="scope.row.comment" placement="top-end" trigger="hover" :content="scope.row.comment">
|
||||
<i v-if="scope.row.comment.length > 25" class="el-icon-info" slot="reference"></i>
|
||||
</el-popover>
|
||||
{{ scope.row.comment || 'بدون پاسخ' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="پاسخ"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-popover v-if="scope.row.replay" placement="top-end" trigger="hover" :content="scope.row.replay">
|
||||
<i v-if="scope.row.replay.length > 25" class="el-icon-info" slot="reference"></i>
|
||||
</el-popover>
|
||||
{{ scope.row.replay || 'بدون پاسخ' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width=""
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" @click="deleteComment(scope.row._id)" :key="scope.row._id + Math.random()">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="primary" variant="outline" @click="openDialog(scope.row._id, scope.row.replay)" :key="scope.row._id + Math.random()">
|
||||
<i class="far fa-comment-alt"></i>
|
||||
</CButton>
|
||||
<CButton
|
||||
variant="outline"
|
||||
:title="scope.row.confirmed ? 'غیرفعال کردن' : 'فعال کردن'"
|
||||
:color="scope.row.confirmed ? 'danger' : 'success'"
|
||||
:key="scope.row._id"
|
||||
@click="changeCommentStatus(scope.row._id,!scope.row.confirmed)"
|
||||
>
|
||||
<i class="fas" :class="scope.row.confirmed ? 'fa-do-not-enter' : 'fa-check'"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<el-dialog
|
||||
title="پاسخ"
|
||||
:visible.sync="dialogVisible"
|
||||
width="50%">
|
||||
<CTextarea
|
||||
:class="validation.replay ? 'err' : null"
|
||||
placeholder="پیام خود را وارد کنید"
|
||||
:description="validation.replay ? validation.replay.msg : null"
|
||||
v-model="replay"/>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="success" @click="addReply">ارسال</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axiosUploadProcess from "@/mixins/axiosUploadProcess"
|
||||
import moment from "moment-jalaali"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
foods: null,
|
||||
foodCategories: null,
|
||||
menuTypes: null,
|
||||
food: null,
|
||||
validation: {},
|
||||
dialogVisible : false,
|
||||
replay : '',
|
||||
commentId : ''
|
||||
}
|
||||
},
|
||||
mixins: [axiosUploadProcess],
|
||||
computed: {
|
||||
title() {
|
||||
return this.$route.params.food === 'new' ? 'افزودن غذا' : 'مشاهده غذا'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openDialog(id , text){
|
||||
this.commentId = id
|
||||
this.replay = text
|
||||
this.dialogVisible = true
|
||||
},
|
||||
jDate(date) {
|
||||
return moment(date).format('jYYYY/jMM/jDD')
|
||||
},
|
||||
imagePreview(e) {
|
||||
this.food.image = URL.createObjectURL(e.target.files[0])
|
||||
},
|
||||
changeCommentStatus(id, status) {
|
||||
this.$axios.post(`/api/admin/commentStatus/${id}`, {confirmed: status})
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'وضعیت کامنت یا موفقیت تغییر کرد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
if (err) console.log(err)
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: 'مشکلی پیش آمده، لطفا دوباره تلاش کنید'
|
||||
})
|
||||
})
|
||||
},
|
||||
addReply(){
|
||||
this.validation = {}
|
||||
this.$axios.post(`/api/admin/replayComment/${this.commentId}`, {replay: this.replay})
|
||||
.then(res => {
|
||||
this.dialogVisible = false;
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'پاسخ با موفقیت ثبت شد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.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 === 500) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "مشکلی در ارسال درخواست پیش آمده",
|
||||
});
|
||||
}
|
||||
if (err.response.status === 422){
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'پارامترها را بررسی کنید'
|
||||
})
|
||||
this.validation = err.response.data.validation;
|
||||
} else console.log(err.response.data);
|
||||
})
|
||||
},
|
||||
deleteComment(id){
|
||||
this.$confirm("کامنت حذف شود؟", "اخطار", {
|
||||
confirmButtonText: "بله",
|
||||
cancelButtonText: "لغو",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
this.validation = {}
|
||||
this.$axios.delete(`/api/admin/deleteComment/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'کامنت با موفقیت حذف شد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.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 === 500) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "مشکلی در ارسال درخواست پیش آمده",
|
||||
});
|
||||
}
|
||||
if (err.response.status === 422){
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'پارامترها را بررسی کنید'
|
||||
})
|
||||
this.validation = err.response.data.validation;
|
||||
} else console.log(err.response.data);
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: "warning",
|
||||
message: "عملیات لغو شد",
|
||||
});
|
||||
});
|
||||
},
|
||||
post() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('name', this.food.name)
|
||||
data.append('price', this.food.price)
|
||||
data.append('description', this.food.description)
|
||||
data.append('short_description', this.food.short_description)
|
||||
this.food.estimated_time && data.append('estimated_time', this.food.estimated_time)
|
||||
data.append('stock', this.food.stock)
|
||||
data.append('category', this.food.category)
|
||||
data.append('static_discount', this.food.static_discount)
|
||||
data.append('special', this.food.special)
|
||||
data.append('index', this.food.index)
|
||||
data.append('havePoint', this.food.havePoint)
|
||||
data.append('club', this.food.club)
|
||||
data.append('point', this.food.point)
|
||||
data.append('sale', this.food.sale)
|
||||
data.append('branchId', this.$route?.params?.branch)
|
||||
if (this.$refs.image.files[0]) data.append('image', this.$refs.image.files[0])
|
||||
|
||||
this.$axios.post(`/api/admin/food`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'غذا با موفقیت ایجاد شد.'
|
||||
})
|
||||
this.$router.push({name: 'admin-branch-foods'})
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('name', this.food.name)
|
||||
data.append('price', this.food.price)
|
||||
data.append('description', this.food.description || '')
|
||||
data.append('short_description', this.food.short_description || '')
|
||||
this.food.estimated_time && data.append('estimated_time', this.food.estimated_time)
|
||||
data.append('stock', this.food.stock)
|
||||
data.append('category', this.food.category)
|
||||
data.append('static_discount', this.food.static_discount)
|
||||
data.append('special', this.food.special)
|
||||
data.append('index', this.food.index)
|
||||
data.append('havePoint', this.food.havePoint)
|
||||
data.append('club', this.food.club)
|
||||
data.append('point', this.food.point)
|
||||
data.append('sale', this.food.sale)
|
||||
data.append('branchId', this.$route?.params?.branch)
|
||||
if (this.$refs.image.files[0]) data.append('image', this.$refs.image.files[0])
|
||||
|
||||
this.$axios.put(`/api/admin/food/${this.food._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
this.$refs.image.value = null
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, error }) {
|
||||
try {
|
||||
const foods = await $axios.get(`/api/public/foods/getAll/${params?.branch}`)
|
||||
const menuTypes = await $axios.get(`/api/public/menuTypes/getAll/${params?.branch}`)
|
||||
const foodCategories = await $axios.get(`/api/public/foodCategories/getAll/${params?.branch}`)
|
||||
if (params.food !== 'new') {
|
||||
const food = await $axios.get(`/api/admin/food/${params.food}`)
|
||||
return {
|
||||
foods: foods.data,
|
||||
menuTypes: menuTypes.data,
|
||||
foodCategories: foodCategories.data,
|
||||
food: food.data
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
foods: foods.data,
|
||||
menuTypes: menuTypes.data,
|
||||
foodCategories: foodCategories.data,
|
||||
food: {
|
||||
name: '',
|
||||
image: '',
|
||||
price: 0,
|
||||
stock: 0,
|
||||
description: '',
|
||||
short_description: '',
|
||||
estimated_time: '',
|
||||
category: '',
|
||||
static_discount: 0,
|
||||
index: 0,
|
||||
special : false,
|
||||
havePoint : false,
|
||||
club : false,
|
||||
sale: true,
|
||||
point : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.callout {
|
||||
border: 0.5px solid rgba(#000, 0.3);
|
||||
border-right: 6px solid blue;
|
||||
border-radius: 5px;
|
||||
padding: 3px 5px;
|
||||
|
||||
&.rate {
|
||||
border-right: 5px solid goldenrod;
|
||||
|
||||
i {
|
||||
color: goldenrod;
|
||||
font-size: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" :to="{name: 'admin-branch-foods-food',params:{food: 'new'}}" class="mr-auto">
|
||||
افزودن</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-filter"></i>
|
||||
<span style="color:#000">فیلتر</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol md="6">
|
||||
<CRow style="flex-direction : column;">
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>نام</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-input style="width : 100%" placeholder="" v-model="search.name"></el-input>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>دسته بندی</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-select filterable clearable style="width : 100%" v-model="search.category"
|
||||
placeholder="">
|
||||
<el-option
|
||||
v-for="item in foodCategories"
|
||||
:key="item._id"
|
||||
:value="item._id"
|
||||
:label="item.name"/>
|
||||
</el-select>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
|
||||
<CCol md="6">
|
||||
<CRow style="flex-direction : column;">
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>فروش به صورت عادی</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-select v-model="search.sale" clearable style="width : 100%">
|
||||
<el-option :key="1" label="بله" :value="true"></el-option>
|
||||
<el-option :key="2" label="خیر" :value="false"></el-option>
|
||||
</el-select>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>فروش در باشگاه مشتریان</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-select v-model="search.club" clearable style="width : 100%">
|
||||
<el-option :key="1" label="بله" :value="true"></el-option>
|
||||
<el-option :key="2" label="خیر" :value="false"></el-option>
|
||||
</el-select>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<el-button :loading="loading" @click="handleSearch" size="small"
|
||||
style="width: auto;margin: 25px auto auto auto;" type="primary"
|
||||
icon="el-icon-search">
|
||||
جست و جو
|
||||
</el-button>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="foods.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="عکس"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<img v-if="scope.row.image" :src="scope.row.image" alt="" style="width: 100px;">
|
||||
<i v-else class="fal fa-image-polaroid" style="font-size: 115px;"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="قیمت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.price">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
<span v-else class="text-danger">بدون قیمت</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column
|
||||
label="قیمت با تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.static_discount">{{ (scope.row.price - (scope.row.price / 100) * scope.row.static_discount).toLocaleString() + ' ريال ' }}</span>
|
||||
<span v-else class="text-danger">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تعداد موجود"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.stock" class="text-success">{{ scope.row.stock }}</span>
|
||||
<span v-else class="text-danger">اتمام موجودی</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="درصد تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.static_discount" class="text-success">{{ scope.row.static_discount + '%' }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="امتیاز مشتریان"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.rate }}</span>
|
||||
<i class="fas fa-star" style="color: goldenrod;"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="دسته بندی"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ getFoodCategoryName(scope.row.category) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="remove(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="success" variant="outline" :key="scope.row._id" :to="{name: 'admin-branch-foods-food',params:
|
||||
{food: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="foods.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="foods.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="foods.page" :total="foods.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const _ = require('lodash');
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست غذاها',
|
||||
list_title: 'لیست',
|
||||
foodCategories: null,
|
||||
foods: null,
|
||||
loading : false,
|
||||
search: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
if (!_.isEmpty(this.search)) {
|
||||
this.handleSearch(page);
|
||||
} else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-foods",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
getFoodCategoryName(id) {
|
||||
return this.foodCategories.filter(item => item._id === id)[0].name
|
||||
},
|
||||
remove(id) {
|
||||
this.$confirm('این مورد حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/food/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'غذا با موفقیت حذف شد'
|
||||
})
|
||||
this.foods.docs = this.foods.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
|
||||
})
|
||||
} else console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
},
|
||||
handleSearch(page) {
|
||||
this.loading = true;
|
||||
|
||||
const data = {
|
||||
club: this.search.club,
|
||||
sale: this.search.sale,
|
||||
name: this.search.name,
|
||||
category: this.search.category,
|
||||
branchId: this.$route?.params?.branch
|
||||
}
|
||||
|
||||
this.$axios.post(`/api/admin/food/search?page=${page}`, data, this.axiosConfig)
|
||||
.then((result) => {
|
||||
this.foods = 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, params}) {
|
||||
try {
|
||||
const foodCategories = await $axios.get(`/api/public/foodCategories/getAll/${params.branch}`)
|
||||
const foods = await $axios.get(`/api/admin/food/getAll/${params.branch}?page=${query.page || 1}`)
|
||||
return {
|
||||
foodCategories: foodCategories.data,
|
||||
foods: foods.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<!-- <CButton size="sm" color="success" :to="{name: 'admin-foods-food',params:{food: 'new'}}" class="mr-auto">افزودن</CButton>-->
|
||||
</CustomSubHeader>
|
||||
<CCard v-if="hasPermission('super-admin')">
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol col="12" sm="6">
|
||||
<CCallout color="info">
|
||||
<small class="text-muted">تعداد مشتری ها</small><br>
|
||||
<strong class="h4">{{ customers.length }}</strong>
|
||||
</CCallout>
|
||||
</CCol>
|
||||
<CCol col="12" sm="6">
|
||||
<CCallout color="danger">
|
||||
<small class="text-muted">تعداد سفارشات</small><br>
|
||||
<strong class="h4">{{ orders.length }}</strong>
|
||||
</CCallout>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCol v-if="hasPermission('super-admin')">
|
||||
<CRow>
|
||||
<CCol sm="6">
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<strong>
|
||||
<span>تعداد مشتریان بر اساس شغل</span>
|
||||
</strong>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<canvas id="myChart" width="400" height="400"></canvas>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
<CCard v-if="hasPermission('super-admin')">
|
||||
<CCardHeader>
|
||||
<strong>
|
||||
<span>لیست تخفیف های ویژه امروز مورخ: </span>
|
||||
<span>{{ jDate(Date.now()) }}</span>
|
||||
</strong>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="offFoods"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="عکس"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<img v-if="scope.row.image" :src="scope.row.image" alt="" style="width: 100px;">
|
||||
<i v-else class="fal fa-image-polaroid" style="font-size: 115px;"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="قیمت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span class="text-success" v-if="scope.row.price">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
<span class="text-danger" v-else>بدون قیمت</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="قیمت با تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.static_discount">{{ (scope.row.price - (scope.row.price / 100) * scope.row.static_discount).toLocaleString() + ' ريال ' }}</span>
|
||||
<span v-else class="text-danger">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تعداد موجود"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span class="text-success" v-if="scope.row.stock">{{ scope.row.stock }}</span>
|
||||
<span class="text-danger" v-else>اتمام موجودی</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="درصد تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span class="text-success" v-if="scope.row.static_discount">{{ scope.row.static_discount + '%' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="دسته بندی"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ getFoodCategoryName(scope.row.category) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column
|
||||
label="مشاهده"
|
||||
width="75"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="success" variant="outline" :key="scope.row._id" :to="{name: 'admin-foods-food',params: {food: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from "moment-jalaali"
|
||||
import login from "@/pages/admin/login";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'داشبورد',
|
||||
list_title: 'لیست',
|
||||
foodCategories: null,
|
||||
foods: null,
|
||||
idToken: '',
|
||||
permissionGranted: false,
|
||||
customers : null,
|
||||
orders : null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
offFoods() {
|
||||
return this.foods.filter(item => item.static_discount)
|
||||
},
|
||||
branchId(){
|
||||
return this.$store?.state?.admin?.branchId
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
jDate(date) {
|
||||
return moment(date).format("jYYYY/jMM/jDD")
|
||||
},
|
||||
getFoodCategoryName(id) {
|
||||
return this.foodCategories.filter(item => item._id === id)[0].name
|
||||
},
|
||||
hasPermission(permission) {
|
||||
if (this.$auth.loggedIn) return this.$auth.user.permissions.includes(permission)
|
||||
else return false
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await Notification.requestPermission()
|
||||
const typePermission = await Notification.permission
|
||||
this.permissionGranted = typePermission === 'granted'
|
||||
|
||||
const getAdmin = this.$auth.$state.user
|
||||
|
||||
if (typePermission === 'granted') {
|
||||
if (getAdmin) {
|
||||
this.idToken = await this.$fire.messaging.getToken()
|
||||
|
||||
await this.$axios.post('/api/admin/addFcmToken', {
|
||||
fcmToken: this.idToken
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.hasPermission('super-admin')){
|
||||
const counts = {};
|
||||
this.customers.forEach(function (x) { counts[x.job] = (counts[x.job] || 0) + 1; });
|
||||
let keys = Object.keys(counts).map(item => item === 'undefined' ? 'نامشخص' : item);
|
||||
let values = Object.values(counts).map(item => item === 'undefined' ? 'نامشخص' : item);
|
||||
|
||||
const CHART_COLORS = {
|
||||
red: 'rgb(255, 99, 132)',
|
||||
orange: 'rgb(255, 159, 64)',
|
||||
yellow: 'rgb(255, 205, 86)',
|
||||
green: 'rgb(75, 192, 192)',
|
||||
blue: 'rgb(54, 162, 235)',
|
||||
purple: 'rgb(153, 102, 255)',
|
||||
grey: 'rgb(201, 203, 207)'
|
||||
};
|
||||
|
||||
const ctx = document.getElementById('myChart');
|
||||
const myChart = new Chart(ctx, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: keys,
|
||||
datasets: [{
|
||||
// label: '# of Votes',
|
||||
data: values,
|
||||
backgroundColor: Object.values(CHART_COLORS),
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, error , redirect , route}) {
|
||||
try {
|
||||
const branchId = route?.params?.branch
|
||||
const requests = [
|
||||
$axios.get(`/api/public/foodCategories/getAll/${branchId}`),
|
||||
$axios.get(`/api/public/foods/getAll/${branchId}`,{progress: false}),
|
||||
$axios.get(`/api/admin/users/forReport/${branchId}`,{progress: false}),
|
||||
$axios.get(`/api/admin/order/forReport/${branchId}`,{progress: false})
|
||||
];
|
||||
|
||||
const fetch = await Promise.all(requests);
|
||||
|
||||
const [foodCategories, foods, customers, orders] = fetch;
|
||||
|
||||
return {
|
||||
foodCategories: foodCategories.data,
|
||||
foods: foods.data,
|
||||
customers: customers.data,
|
||||
orders: orders.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
redirect('/admin/login')
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-jobs'}">برگشت به صفحه قبل</CButton>
|
||||
<CButton v-if="$route.params.type === 'new'" size="sm" color="success" class="mr-1" @click="post">افزودن</CButton>
|
||||
<CButton v-else size="sm" color="success" class="mr-1" @click="update">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<!-- <template v-if="$route.params.profile !== 'new'">-->
|
||||
<!-- <h4>مشخصات منو</h4>-->
|
||||
<!-- <el-divider/>-->
|
||||
<!-- </template>-->
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.name ? 'err' : null"
|
||||
label="نام"
|
||||
:description="validation.name ? validation.name.msg : null"
|
||||
v-model="job.name"
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCol s="12" class="mt-3">
|
||||
<span>ترتیب نمایش در منو</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="job.index" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option
|
||||
v-for="item in 1000"
|
||||
v-if="!jobs.filter(item2=>Number(item2.index) === item).length"
|
||||
:key="item + 202"
|
||||
:value="item"
|
||||
:label="item"/>
|
||||
</el-select>
|
||||
<p v-if="validation.index" class="text-danger" style="margin-top: 5px;">{{ validation.index.msg }}</p>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
|
||||
</CRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
jobs: null,
|
||||
job: null,
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.$route.params.type === 'new' ? 'افزودن شغل' : 'مشاهده شغل'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
post() {
|
||||
this.validation = {}
|
||||
const data = this.job
|
||||
this.$axios.post(`/api/admin/job`, data)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'شغل با موفقیت ایجاد شد.'
|
||||
})
|
||||
this.$router.push({name: 'admin-branch-jobs'})
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = this.job
|
||||
this.$axios.put(`/api/admin/job/${this.job._id}`, data)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, error}) {
|
||||
try {
|
||||
const jobs = await $axios.get(`/api/public/job`)
|
||||
if (params.type !== 'new') {
|
||||
const job = await $axios.get(`/api/admin/job/${params.type}`)
|
||||
return {
|
||||
jobs: jobs.data,
|
||||
job: job.data
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
jobs: jobs.data,
|
||||
job: {
|
||||
name: '',
|
||||
index: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" :to="{name: 'admin-branch-jobs-type',params:{type: 'new'}}"
|
||||
class="mr-auto">افزودن
|
||||
</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="jobs.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="remove(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="success" variant="outline" :key="scope.row._id" :to="{name: 'admin-branch-jobs-type',params:
|
||||
{type: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="jobs.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="jobs.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="jobs.page" :total="jobs.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست انواع منوها',
|
||||
list_title: 'لیست',
|
||||
jobs: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-menu-types",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
remove(id) {
|
||||
this.$confirm('این مورد حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/job/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'منو با موفقیت حذف شد'
|
||||
})
|
||||
this.jobs.docs = this.jobs.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
|
||||
})
|
||||
} else console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios,query , error}) {
|
||||
try {
|
||||
const jobs = await $axios.get(`/api/admin/job?page=${query.page || 1}`)
|
||||
return {
|
||||
jobs: jobs.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-menu-types'}">برگشت به صفحه
|
||||
قبل</CButton>
|
||||
<CButton v-if="$route.params.type === 'new'" size="sm" color="success" class="mr-1" @click="post">افزودن</CButton>
|
||||
<CButton v-else size="sm" color="success" class="mr-1" @click="update">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<!-- <template v-if="$route.params.profile !== 'new'">-->
|
||||
<!-- <h4>مشخصات منو</h4>-->
|
||||
<!-- <el-divider/>-->
|
||||
<!-- </template>-->
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.name ? 'err' : null"
|
||||
label="نام"
|
||||
:description="validation.name ? validation.name.msg : null"
|
||||
v-model="menuType.name"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="menuType.showOnWebSite">در وبسایت نمایش داده شود</el-checkbox>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="menuType.isCafeMenu">منوی کافه است</el-checkbox>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCol s="12" class="mt-3">
|
||||
<span>ترتیب نمایش در منو</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="menuType.index" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option
|
||||
v-for="item in 1000"
|
||||
v-if="!menuTypes.filter(item2=>Number(item2.index) === item).length"
|
||||
:key="item + 202"
|
||||
:value="item"
|
||||
:label="item"/>
|
||||
</el-select>
|
||||
<p v-if="validation.index" class="text-danger" style="margin-top: 5px;">{{ validation.index.msg }}</p>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
|
||||
</CRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
menuTypes: null,
|
||||
menuType: null,
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.$route.params.type === 'new' ? 'افزودن منو' : 'مشاهده منو'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
post() {
|
||||
this.validation = {}
|
||||
const data = this.menuType
|
||||
data.branchId = this.$route?.params?.branch
|
||||
this.$axios.post(`/api/admin/menuType`, data)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'منو با موفقیت ایجاد شد.'
|
||||
})
|
||||
this.$router.push({name: 'admin-branch-menu-types'})
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = this.menuType
|
||||
data.branchId = this.$route?.params?.branch
|
||||
this.$axios.put(`/api/admin/menuType/${this.menuType._id}`, data)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, error}) {
|
||||
try {
|
||||
const menuTypes = await $axios.get(`/api/public/menuTypes/getAll/${params?.branch}`)
|
||||
if (params.type !== 'new') {
|
||||
const menuType = await $axios.get(`/api/public/menuType/${params.type}`)
|
||||
return {
|
||||
menuTypes: menuTypes.data,
|
||||
menuType: menuType.data
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
menuTypes: menuTypes.data,
|
||||
menuType: {
|
||||
name: '',
|
||||
showOnWebSite: true,
|
||||
isCafeMenu: false,
|
||||
index: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" :to="{name: 'admin-branch-menu-types-type',params:{type: 'new'}}"
|
||||
class="mr-auto">افزودن</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="menuTypes.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="remove(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="success" variant="outline" :key="scope.row._id"
|
||||
:to="{name: 'admin-branch-menu-types-type',params: {type: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="menuTypes.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="menuTypes.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="menuTypes.page" :total="menuTypes.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست انواع منوها',
|
||||
list_title: 'لیست',
|
||||
menuTypes: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-menu-types",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
remove(id) {
|
||||
this.$confirm('این مورد حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/menuType/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'منو با موفقیت حذف شد'
|
||||
})
|
||||
this.menuTypes.docs = this.menuTypes.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
|
||||
})
|
||||
} else console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios,query , error, params}) {
|
||||
try {
|
||||
const menuTypes = await $axios.get(`/api/admin/menuType/getAll/${params?.branch}?page=${query.page || 1}`)
|
||||
return {
|
||||
menuTypes: menuTypes.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<!-- <CButton size="sm" color="success" class="mr-auto" @click="addInfo">بروزرسانی</CButton>-->
|
||||
</CustomSubHeader>
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CCol lg="6" sm="12">
|
||||
<el-switch
|
||||
style="display: flex; direction: ltr!important; justify-content: right"
|
||||
v-model="notif.multi"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
active-text="ارسال عمومی"
|
||||
inactive-text="ارسال اختصاصی">
|
||||
</el-switch>
|
||||
<!-- <el-checkbox v-model="notif.multi" label="ارسال عمومی"/>-->
|
||||
</CCol>
|
||||
<CCol class="mt-4" v-if="!notif.multi" lg="6" sm="12">
|
||||
<el-select
|
||||
v-model="notif.user_id"
|
||||
filterable
|
||||
style="width: 300px;margin-top: 20px;margin-bottom: 10px;">
|
||||
<el-option
|
||||
v-for="item in users"
|
||||
:key="item._id"
|
||||
:value="item._id"
|
||||
:label="item.business_code + ' ' + '(' + item.first_name + ' ' + item.last_name + ')'"/>
|
||||
</el-select>
|
||||
</CCol>
|
||||
<CCol class="mt-4" sm="12" lg="6">
|
||||
<CInput
|
||||
:class="validation.title ? 'err' : null"
|
||||
label="عنوان"
|
||||
:description="validation.title ? validation.title.msg : null"
|
||||
v-model="notif.title"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol class="mt-4" sm="12" lg="6">
|
||||
<CTextarea
|
||||
:class="validation.body ? 'err' : null"
|
||||
label="متن پیام"
|
||||
:description="validation.body ? validation.body.msg : null"
|
||||
v-model="notif.body"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol class="mt-4" sm="12" lg="6">
|
||||
<el-button type="success" @click="sendNotification">ارسال</el-button>
|
||||
</CCol>
|
||||
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment-jalaali'
|
||||
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'ارسال نوتیفیکیشن',
|
||||
list_title: 'لیست',
|
||||
// base data
|
||||
notif: {
|
||||
multi: true,
|
||||
user_id: '',
|
||||
title: '',
|
||||
body: '',
|
||||
},
|
||||
users: null,
|
||||
// validation
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendNotification() {
|
||||
this.validation = {}
|
||||
this.$axios.post('/api/admin/notification', this.notif)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'نوتیفیکیشن با موفقیت ارسال شد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.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 === 500) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "مشکلی در ارسال درخواست پیش آمده",
|
||||
});
|
||||
}
|
||||
if (err.response.status === 422) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'پارامترها را بررسی کنید'
|
||||
})
|
||||
this.validation = err.response.data.validation;
|
||||
} else console.log(err.response.data);
|
||||
});
|
||||
},
|
||||
jDate(date) {
|
||||
return moment(date, 'X').format('jYYYY/jMM/jDD')
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, error , params}) {
|
||||
try {
|
||||
const users = await $axios.get(`/api/admin/users/getAll/${params?.branch}`)
|
||||
return {
|
||||
users: users.data,
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.el-button:focus {
|
||||
outline-color: #39f !important;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100vh;
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
.holder-logo {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-attrib-button {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,775 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-orders'}">برگشت به صفحه قبل</CButton>
|
||||
<CButton size="sm" color="danger" class="mr-1" @click="remove">حذف</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<span><b><i class="fal fa-info-circle"></i></b></span>
|
||||
<span><b>اطلاعات</b></span>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<CRow>
|
||||
<el-card class="box-card">
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>شماره سفارش:</span>
|
||||
<span>{{ order.number }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>تاریخ ایجاد:</span>
|
||||
<span>{{ jDate(order.createdOn) }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>توضیحات سفارش:</span>
|
||||
<span>{{ order.description }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>مشتری:</span>
|
||||
<nuxt-link :to="{name : 'admin-branch-customers-profile' , params : {profile : order.user_id._id}}">
|
||||
{{ order.user_id.first_name + ' ' + order.user_id.last_name }}
|
||||
</nuxt-link>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>وضعیت سفارش:</span>
|
||||
<span>
|
||||
<b>
|
||||
<el-tag
|
||||
size="medium"
|
||||
:type="showOrderStatus(order.status).type "
|
||||
effect="dark">
|
||||
<span>{{ showOrderStatus(order.status).message }}</span>
|
||||
</el-tag>
|
||||
</b>
|
||||
</span>
|
||||
<el-button type="info" size="medium" class="mr-1" @click="openChangeStatus(order.status)">تغییر وضعیت</el-button>
|
||||
</CCol>
|
||||
</el-card>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<el-card class="box-card mt-4">
|
||||
<CCol v-if="order.orderType === 'online'" class="m-2" sm="12">
|
||||
<span>مجموع:</span>
|
||||
<span>{{ order.sum.toLocaleString() + ' ریال' }}</span>
|
||||
</CCol>
|
||||
<CCol v-if="order.orderType === 'online'" class="m-2" sm="12">
|
||||
<span>هزینه ارسال:</span>
|
||||
<span>{{ order.routePrice.toLocaleString() + ' ریال' }}</span>
|
||||
</CCol>
|
||||
<CCol v-if="order.orderType === 'online'" class="m-2" sm="12">
|
||||
<span>مالیات:</span>
|
||||
<span>{{ order.tax.toLocaleString() + ' ریال' }}</span>
|
||||
</CCol>
|
||||
<CCol v-if="order.orderType === 'online'" class="m-2" sm="12">
|
||||
<span>تخفیف:</span>
|
||||
<span>{{ order.percent.toLocaleString() + ' ریال' }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12" v-if="order.discount_code">
|
||||
<span>کد تخفیف:</span>
|
||||
<span>{{ order.discount_code }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12" v-if="order.discount_code">
|
||||
<span>درصد تخفیف:</span>
|
||||
<span>{{ order.discount_amount }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>جمع کل:</span>
|
||||
<span v-if="order.orderType === 'online'">{{ order.total.toLocaleString() + ' ریال' }}</span>
|
||||
<span v-else>{{ order.total + ' امتیاز' }}</span>
|
||||
</CCol>
|
||||
</el-card>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<el-card class="box-card mt-4">
|
||||
<CCol class="m-2" v-if="order.payment.length">
|
||||
<CCardHeader>
|
||||
<!-- <span><b><i class="fal fal fa-utensils"></i></b></span>-->
|
||||
<span><b>لیست تراکنشات</b></span>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="order.payment"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="شناسه تراکنش"
|
||||
width="350"
|
||||
prop="transactionId"/>
|
||||
|
||||
<el-table-column
|
||||
label="شماره پیگیری"
|
||||
width=""
|
||||
prop="refId"/>
|
||||
|
||||
<el-table-column
|
||||
label="نوع تراکنش"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
type="success"
|
||||
effect="dark">
|
||||
<span>{{
|
||||
scope.row.action === 'increaseBag' ? 'افزایش کیف پول' : scope.row.action === 'decreaseBag' ? 'کاهش کیف پول' : 'پرداخت اینترنتی'
|
||||
}}
|
||||
</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="وضعیت پرداخت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="scope.row.status === 'paid' ? 'success' : 'danger' "
|
||||
effect="dark">
|
||||
<span>{{ scope.row.status === 'paid' ? 'پرداخت موفق' : 'پرداخت ناموفق' }}</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="مبلغ"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.cost.toLocaleString() + ' ریال' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ و ساعت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDate(scope.row.created_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCol>
|
||||
<CCol class="m-2" v-if="scoreLogs.length">
|
||||
<CCardHeader>
|
||||
<!-- <span><b><i class="fal fal fa-utensils"></i></b></span>-->
|
||||
<span><b>لیست امتیازات استفاده شده</b></span>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="scoreLogs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="نوع"
|
||||
width="">
|
||||
کاهش
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="وضعیت پرداخت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
type="success"
|
||||
effect="dark">
|
||||
<span>پرداخت موفق</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="امتیاز"
|
||||
width=""
|
||||
prop="score"/>
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="مبلغ به ازای امتیاز"-->
|
||||
<!-- width="">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- {{ (scope.row.score*pointPrice).toLocaleString() + ' ریال' }}-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ و ساعت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
{{ jDate(scope.row.created_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCol>
|
||||
<!-- <CCol class="m-2" sm="12" v-if="order.bag">-->
|
||||
<!-- <span>مقدار پرداخت شده از کیف پول:</span>-->
|
||||
<!-- <span>{{ order.discount_amount }}</span>-->
|
||||
<!-- </CCol>-->
|
||||
<!-- <CCol class="m-2" sm="12" v-if="order.payment">-->
|
||||
<!-- <span>شماره پیگیری:</span>-->
|
||||
<!-- <span v-if="order.payment.length">{{ order.payment[0].refId }}</span>-->
|
||||
<!-- </CCol>-->
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>وضعیت پرداخت:</span>
|
||||
<span>
|
||||
<b>
|
||||
<el-tag
|
||||
size="medium"
|
||||
:type="showPaymentStatus(order.paymentStatus).type"
|
||||
effect="dark">
|
||||
<span>{{ showPaymentStatus(order.paymentStatus).message }}</span>
|
||||
</el-tag>
|
||||
</b>
|
||||
</span>
|
||||
<!-- <el-button type="info" size="medium" class="mr-1" @click="openChangePayStatus(order.paymentStatus)">تغییر وضعیت</el-button>-->
|
||||
</CCol>
|
||||
</el-card>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<span><b><i class="fal fa-map-marker-alt"></i></b></span>
|
||||
<span><b>آدرس</b></span>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<CRow v-if="order.address">
|
||||
<el-card class="box-card">
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>عنوان:</span>
|
||||
<span>{{ order.address.title }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>استان:</span>
|
||||
<span>{{ order.address.province }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>شهر:</span>
|
||||
<span>{{ order.address.city }}</span>
|
||||
</CCol>
|
||||
<CCol class="m-2" sm="12">
|
||||
<span>آدرس:</span>
|
||||
<span>{{ order.address.address }}</span>
|
||||
</CCol>
|
||||
</el-card>
|
||||
<el-card class="box-card mt-4 text-center">
|
||||
<template>
|
||||
<no-ssr>
|
||||
<mapir class="d-inline-flex" id="map" :min-zoom="12" :max-zoom="18" :zoom="15" logo-position="top-left" :center="order.address.location.coordinates || center" :apiKey="apiKey">
|
||||
<mapNavigationControl position="top-right"/>
|
||||
<mapMarker
|
||||
:coordinates.sync="order.address.location.coordinates || center"
|
||||
color="red"
|
||||
:draggable="false"
|
||||
/>
|
||||
</mapir>
|
||||
</no-ssr>
|
||||
</template>
|
||||
</el-card>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<span><b><i class="fal fal fa-utensils"></i></b></span>
|
||||
<span><b>سفارشات</b></span>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="order.order_items"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="عکس"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<img v-if="scope.row.product_id" :src="scope.row.product_id.image" alt="" style="width: 100px;">
|
||||
<i v-else class="fal fa-image-polaroid" style="font-size: 115px;"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="نام"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.product_id">{{ scope.row.product_id.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
:label="order.orderType === 'club' ? 'امتیاز' : 'قیمت'"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="order.orderType === 'club'">
|
||||
<span v-if="scope.row.point">{{ scope.row.point + ' امتیاز ' }}</span>
|
||||
<span v-else class="text-danger">-</span>
|
||||
</span>
|
||||
<span v-else>
|
||||
<span v-if="scope.row.price">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
<span v-else class="text-danger">-</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-if="order.orderType === 'online'"
|
||||
label="قیمت با تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.static_discount">{{ (scope.row.price - (scope.row.price / 100) * scope.row.static_discount).toLocaleString() + ' ريال ' }}</span>
|
||||
<span v-else class="text-danger">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-if="order.orderType === 'online'"
|
||||
label="درصد تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.static_discount" class="text-success">{{ scope.row.static_discount + '%' }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="تعداد"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.quantity" class="text-success">{{ scope.row.quantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-if="order.orderType === 'online'"
|
||||
label="جمع بدون تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.quantity" class="text-success">{{ (scope.row.price * scope.row.quantity).toLocaleString() + ' ریال' }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-if="order.orderType === 'online'"
|
||||
label="جمع با تخفیف"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.quantity" class="text-success">
|
||||
{{ ((scope.row.price - (scope.row.price / 100) * scope.row.static_discount) * scope.row.quantity).toLocaleString() + ' ریال' }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="مشتری"-->
|
||||
<!-- width="">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <nuxt-link v-if="scope.row.user_id" :to="{name: 'admin-customers-profile',params: {profile: scope.row.user_id._id}}">{{ scope.row.user_id.first_name + ' ' + scope.row.user_id.last_name }}</nuxt-link>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="جمع کل"-->
|
||||
<!-- width="">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <span>{{ scope.row.total.toLocaleString() + ' ریال' }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="وضعیت سفارش"-->
|
||||
<!-- width="">-->
|
||||
<!-- <template slot-scope="scope" :v-html="showOrderStatus(scope.row.status)">-->
|
||||
<!-- <el-tag-->
|
||||
<!-- :type="showOrderStatus(scope.row.status).type"-->
|
||||
<!-- effect="dark">-->
|
||||
<!-- <span>{{ showOrderStatus(scope.row.status).message }}</span>-->
|
||||
<!-- </el-tag>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="وضعیت پرداخت"-->
|
||||
<!-- width="">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <el-tag-->
|
||||
<!-- :type="showPaymentStatus(scope.row.paymentStatus).type"-->
|
||||
<!-- effect="dark">-->
|
||||
<!-- <span>{{ showPaymentStatus(scope.row.paymentStatus).message }}</span>-->
|
||||
<!-- </el-tag>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="مشاهده"-->
|
||||
<!-- width="110"-->
|
||||
<!-- align="center">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <CButton color="success" variant="outline" :key="scope.row._id" :to="{name: 'admin-orders-order',params: {order: scope.row._id}}">-->
|
||||
<!-- <i class="far fa-eye"></i>-->
|
||||
<!-- </CButton>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<el-dialog
|
||||
title="تغییر وضعیت سفارش"
|
||||
:visible.sync="dialogVisible"
|
||||
width="50%">
|
||||
<el-select v-model="status" placeholder="">
|
||||
<el-option
|
||||
v-for="item in allStatus"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button type="success" class="mr-1" @click="updateStatus">ارسال</el-button>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
title="تغییر وضعیت پرداخت"
|
||||
:visible.sync="dialogVisiblePay"
|
||||
width="50%">
|
||||
<el-select v-model="statusPay" placeholder="">
|
||||
<el-option
|
||||
v-for="item in allStatusPay"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button type="success" class="mr-1" @click="updatePaymentStatus">ارسال</el-button>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axiosUploadProcess from "@/mixins/axiosUploadProcess"
|
||||
import moment from "moment-jalaali"
|
||||
|
||||
let mapirVue = {}
|
||||
if (process.client)
|
||||
mapirVue = require('mapir-vue')
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'mapir': mapirVue.mapir,
|
||||
'mapMarker': mapirVue.mapMarker,
|
||||
'mapNavigationControl': mapirVue.mapNavigationControl,
|
||||
'mapGeolocateControl': mapirVue.mapGeolocateControl,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
apiKey: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIn0.eyJhdWQiOiIxNDk3OSIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIiwiaWF0IjoxNjI3MzI2Mzc0LCJuYmYiOjE2MjczMjYzNzQsImV4cCI6MTYyOTkxODM3NCwic3ViIjoiIiwic2NvcGVzIjpbImJhc2ljIl19.hyKNSy4fmPps6yIdm33Wof-mES9ujh5lmI3VFWyecbkNCm9ATPwsZ9s53A3a1wPJmHfLBXpCcob5NGL-GjZlVfqfRBiReRMr_iniCjUOnqENfFwVEJutxI-xrzVe7PZzOgx1Vr6WwSUHvQ36eJSS1lBlHlqCgwRbkG0hs4YdZsKhzhfYdlAluNw9djjUAMbRWZVL0EluP9CYko4w8tB0KHUZMZYGQcevCfb_3OU9ygHo7B--Z5aTPfm7IK4eP0gHsZ_t857B3tu3ZJB1mkgxc2R9gZUflKqj1ZqkYiR0uMGP-571enXh6pYQLXL2k-gOxLIedCaE6XytxVXhENnotA',
|
||||
order: null,
|
||||
status: '',
|
||||
statusPay: '',
|
||||
pointPrice : 800,
|
||||
center: [49.6848857, 34.0821617],
|
||||
validation: {},
|
||||
dialogVisible: false,
|
||||
dialogVisiblePay: false,
|
||||
allStatus: [
|
||||
{
|
||||
label: 'لغو شده',
|
||||
value: 'canceled'
|
||||
},
|
||||
{
|
||||
label: 'در حال آماده سازی',
|
||||
value: 'processing'
|
||||
},
|
||||
// {
|
||||
// label: 'ارسال شده',
|
||||
// value: 'sent'
|
||||
// },
|
||||
{
|
||||
label: 'تحویل داده شده',
|
||||
value: 'delivered'
|
||||
}
|
||||
],
|
||||
allStatusPay: [
|
||||
{
|
||||
label: 'بازگشت مبلغ',
|
||||
value: 'refund'
|
||||
},
|
||||
{
|
||||
label: 'پرداخت شده',
|
||||
value: 'paid'
|
||||
},
|
||||
{
|
||||
label: 'پرداخت نشده',
|
||||
value: 'unpaid'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mixins: [axiosUploadProcess],
|
||||
computed: {
|
||||
title() {
|
||||
return 'مشاهده سفارش'
|
||||
},
|
||||
scoreLogs() {
|
||||
return this.order.user_id.scoreLogs.filter(item => item?.order_id === this.order._id && item.forWhat === 'buy' && item.action === 'decrease')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openChangeStatus(status) {
|
||||
this.status = status
|
||||
this.dialogVisible = true
|
||||
},
|
||||
openChangePayStatus(status) {
|
||||
this.statusPay = status
|
||||
this.dialogVisiblePay = true
|
||||
},
|
||||
showPaymentStatus(status) {
|
||||
switch (status) {
|
||||
case 'unpaid':
|
||||
return {
|
||||
type: 'danger',
|
||||
message: 'پرداخت نشده'
|
||||
}
|
||||
case 'paid':
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'پرداخت شده'
|
||||
}
|
||||
case 'refund':
|
||||
return {
|
||||
type: 'warning',
|
||||
message: 'برگشت خورده'
|
||||
}
|
||||
default :
|
||||
return {
|
||||
type: 'info',
|
||||
message: 'وضعیت نا مشخص'
|
||||
}
|
||||
}
|
||||
},
|
||||
showOrderStatus(status) {
|
||||
switch (status) {
|
||||
case 'canceled':
|
||||
return {
|
||||
type: 'danger',
|
||||
message: 'لغو شده'
|
||||
}
|
||||
case 'processing':
|
||||
return {
|
||||
type: 'primary',
|
||||
message: 'در حال آماده سازی'
|
||||
}
|
||||
case 'sent':
|
||||
return {
|
||||
type: 'warning',
|
||||
message: 'ارسال شده'
|
||||
}
|
||||
case 'delivered':
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'تحویل داده شده'
|
||||
}
|
||||
default :
|
||||
return {
|
||||
type: 'info',
|
||||
message: 'وضعیت نا مشخص'
|
||||
}
|
||||
}
|
||||
},
|
||||
jDate(date) {
|
||||
return moment(date).format('jYYYY/jMM/jDD HH:mm')
|
||||
},
|
||||
updateStatus() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('status', this.status)
|
||||
|
||||
this.$axios.put(`/api/admin/order/${this.order._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.dialogVisible = false
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'وضعیت سفارش تغییر کرد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response.status === 401) {
|
||||
return this.$message({
|
||||
type: 'error',
|
||||
message: 'لطفا دوباره وارد سیستم شوید.'
|
||||
})
|
||||
}
|
||||
if (err.response.status === 422) {
|
||||
this.validation = err.response.data.validation
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
|
||||
})
|
||||
} else {
|
||||
this.$alert(err.response.data.error.message, 'خطا', {
|
||||
confirmButtonText: 'باشه'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
updatePaymentStatus() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('status', this.statusPay)
|
||||
|
||||
this.$axios.put(`/api/admin/payments/${this.order._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.dialogVisiblePay = false
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'وضعیت پرداخت تغییر کرد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response.status === 401) {
|
||||
return this.$message({
|
||||
type: 'error',
|
||||
message: 'لطفا دوباره وارد سیستم شوید.'
|
||||
})
|
||||
}
|
||||
if (err.response.status === 422) {
|
||||
this.validation = err.response.data.validation
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: err.response.data.message
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
remove() {
|
||||
this.$confirm('این مورد حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/order/${this.order._id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'سفارش با موفقیت حذف شد'
|
||||
})
|
||||
this.$router.push({
|
||||
name: "admin-branch-orders"
|
||||
});
|
||||
})
|
||||
.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
|
||||
})
|
||||
} else console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, params, error}) {
|
||||
try {
|
||||
const order = await $axios.get(`/api/admin/order/${params.order}`)
|
||||
return {
|
||||
order: order.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#map {
|
||||
width: 100vh;
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
.holder-logo {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-attrib-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.callout {
|
||||
border: 0.5px solid rgba(#000, 0.3);
|
||||
border-right: 6px solid blue;
|
||||
border-radius: 5px;
|
||||
padding: 3px 5px;
|
||||
|
||||
&.rate {
|
||||
border-right: 5px solid goldenrod;
|
||||
|
||||
i {
|
||||
color: goldenrod;
|
||||
font-size: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,423 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-filter"></i>
|
||||
<span style="color:#000">فیلتر</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol md="6">
|
||||
<CRow style="flex-direction : column;">
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>شماره سفارش</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-input style="width : 100%" placeholder="" v-model="search.number"></el-input>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>مشتری</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-select filterable clearable style="width : 100%" v-model="search.userId"
|
||||
placeholder="انتخاب مشتری">
|
||||
<el-option
|
||||
v-for="item in users"
|
||||
:key="item._id"
|
||||
:value="item._id"
|
||||
:label="item.business_code + ' ' + '(' + item.first_name + ' ' + item.last_name + ')'"/>
|
||||
</el-select>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>تاریخ</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<date-picker range clearable format="YYYY-MM-DD" display-format="jMMMM jD"
|
||||
v-model="search.date"></date-picker>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
|
||||
<CCol md="6">
|
||||
<CRow style="flex-direction : column;">
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>وضعیت سفارش</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-select v-model="search.orderStatus" clearable style="width : 100%">
|
||||
<el-option v-for="item in allStatus" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
<CCol class="mt-3">
|
||||
<CRow style="align-items: baseline;">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>وضعیت پرداخت</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<el-select v-model="search.paymentStatus" clearable style="width : 100%">
|
||||
<el-option :key="1" label="پرداخت شده" value="paid">
|
||||
</el-option>
|
||||
<el-option :key="2" label="پرداخت نشده" value="unpaid">
|
||||
</el-option>
|
||||
<el-option :key="3" label="برگشت خورده" value="refund">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<el-button :loading="loading" @click="handleSearch" size="small"
|
||||
style="width: auto;margin: 25px auto auto auto;" type="primary"
|
||||
icon="el-icon-search">
|
||||
جست و جو
|
||||
</el-button>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="orders.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="شماره سفارش"-->
|
||||
<!-- prop="number"-->
|
||||
<!-- width="">-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<el-table-column
|
||||
label="مشتری"
|
||||
min-width="150">
|
||||
<template slot-scope="scope">
|
||||
<nuxt-link v-if="scope.row.user_id"
|
||||
:to="{name: 'admin-branch-customers-profile',params: {profile: scope.row.user_id._id}}">{{
|
||||
scope.row.user_id.first_name + ' ' + scope.row.user_id.last_name }}
|
||||
</nuxt-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="امتیاز"
|
||||
min-width="70">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.scorePoint.toLocaleString() }}</span>
|
||||
<!-- <span>{{ scope.row.orderType === 'club' ? ' امتیاز' : ' ریال'}}</span>-->
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ارزش امتیاز"
|
||||
min-width="110">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.scoreCost.toLocaleString() + ' ریال'}}</span>
|
||||
<!-- <span>{{ scope.row.orderType === 'club' ? ' امتیاز' : ' ریال'}}</span>-->
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="کیف پول"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.bagCost.toLocaleString() + ' ریال' }}</span>
|
||||
<!-- <span>{{ scope.row.orderType === 'club' ? ' امتیاز' : ' ریال'}}</span>-->
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="پرداخت آنلاین"
|
||||
min-width="115">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.payTotal">{{ scope.row.payTotal.toLocaleString() + ' ریال' }}</span>
|
||||
<span v-else>0 ریال</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="جمع کل"
|
||||
min-width="115">
|
||||
<template slot-scope="scope">
|
||||
<el-popover trigger="hover" placement="top">
|
||||
<span>{{ scope.row.total.toLocaleString() }}</span>
|
||||
<span>{{ scope.row.orderType === 'club' ? ' امتیاز' : ' ریال' }}</span>
|
||||
<div slot="reference" class="name-wrapper">
|
||||
<span>{{ scope.row.total.toLocaleString() }}</span>
|
||||
<span>{{ scope.row.orderType === 'club' ? ' امتیاز' : ' ریال' }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="وضعیت سفارش"
|
||||
min-width="120">
|
||||
<template slot-scope="scope" :v-html="showOrderStatus(scope.row.status)">
|
||||
<el-tag
|
||||
:type="showOrderStatus(scope.row.status).type"
|
||||
effect="dark">
|
||||
<span>{{ showOrderStatus(scope.row.status).message }}</span>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column-->
|
||||
<!-- label="وضعیت پرداخت"-->
|
||||
<!-- width="">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <el-tag-->
|
||||
<!-- :type="showPaymentStatus(scope.row.paymentStatus).type"-->
|
||||
<!-- effect="dark">-->
|
||||
<!-- <span>{{ showPaymentStatus(scope.row.paymentStatus).message }}</span>-->
|
||||
<!-- </el-tag>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
|
||||
<el-table-column
|
||||
label="تاریخ"
|
||||
min-width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-popover trigger="hover" placement="top">
|
||||
<p>{{ jDate(scope.row.createdOn) }}</p>
|
||||
<div slot="reference" class="name-wrapper">
|
||||
{{ jDate(scope.row.createdOn) }}
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="مشاهده"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="success" variant="outline" :key="scope.row._id"
|
||||
:to="{name: 'admin-branch-orders-order',params: {order: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="orders.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="orders.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="orders.page" :total="orders.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from "moment-jalaali";
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست سفارشات',
|
||||
list_title: 'لیست',
|
||||
orders: null,
|
||||
search: {},
|
||||
users: null,
|
||||
loading: false,
|
||||
allStatus: [
|
||||
{
|
||||
label: 'لغو شده',
|
||||
value: 'canceled'
|
||||
},
|
||||
{
|
||||
label: 'در حال آماده سازی',
|
||||
value: 'processing'
|
||||
},
|
||||
{
|
||||
label: 'ارسال شده',
|
||||
value: 'sent'
|
||||
},
|
||||
{
|
||||
label: 'تحویل داده شده',
|
||||
value: 'delivered'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
jDate(date) {
|
||||
return moment(date).format('jYYYY/jMM/jDD HH:mm')
|
||||
},
|
||||
showPaymentStatus(status) {
|
||||
switch (status) {
|
||||
case 'unpaid':
|
||||
return {
|
||||
type: 'danger',
|
||||
message: 'پرداخت نشده'
|
||||
}
|
||||
case 'paid':
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'پرداخت شده'
|
||||
}
|
||||
case 'refund':
|
||||
return {
|
||||
type: 'warning',
|
||||
message: 'برگشت خورده'
|
||||
}
|
||||
default :
|
||||
return {
|
||||
type: 'info',
|
||||
message: 'وضعیت نا مشخص'
|
||||
}
|
||||
}
|
||||
},
|
||||
showOrderStatus(status) {
|
||||
switch (status) {
|
||||
case 'canceled':
|
||||
return {
|
||||
type: 'danger',
|
||||
message: 'لغو شده'
|
||||
}
|
||||
case 'processing':
|
||||
return {
|
||||
type: 'primary',
|
||||
message: 'در حال آماده سازی'
|
||||
}
|
||||
case 'sent':
|
||||
return {
|
||||
type: 'warning',
|
||||
message: 'ارسال شده'
|
||||
}
|
||||
case 'delivered':
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'تحویل داده شده'
|
||||
}
|
||||
default :
|
||||
return {
|
||||
type: 'info',
|
||||
message: 'وضعیت نا مشخص'
|
||||
}
|
||||
}
|
||||
},
|
||||
handleCurrentChange(page) {
|
||||
if (!_.isEmpty(this.search)) {
|
||||
this.handleSearch(page);
|
||||
} else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-orders",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
handleSearch(page) {
|
||||
this.loading = true;
|
||||
|
||||
const data = {
|
||||
branchId: this.$route?.params?.branch,
|
||||
number: this.search.number,
|
||||
userId: this.search.userId,
|
||||
orderStatus: this.search.orderStatus,
|
||||
paymentStatus: this.search.paymentStatus,
|
||||
date: this.search.date,
|
||||
}
|
||||
|
||||
this.$axios.post(`/api/admin/order/search?page=${page}`, data, this.axiosConfig)
|
||||
.then((result) => {
|
||||
this.orders = 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 , params}) {
|
||||
try {
|
||||
const order = await $axios.get(`/api/admin/order/getAll/${params?.branch}?page=${query.page || 1}`)
|
||||
const users = await $axios.get(`/api/admin/users/getAll/${params?.branch}`)
|
||||
return {
|
||||
orders: order.data,
|
||||
users: users.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-party-sets'}">برگشت به صفحه قبل</CButton>
|
||||
<CButton v-if="$route.params.set === 'new'" size="sm" color="success" class="mr-1" @click="post">افزودن</CButton>
|
||||
<CButton v-else size="sm" color="success" class="mr-1" @click="update">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CForm>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.title ? 'err' : null"
|
||||
label="عنوان"
|
||||
:description="validation.title ? validation.title.msg : null"
|
||||
v-model="partySet.title"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.description ? 'err' : null"
|
||||
label="توضیحات"
|
||||
:description="validation.description ? validation.description.msg : null"
|
||||
v-model="partySet.description"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.price ? 'err' : null"
|
||||
label="قیمت (ريال)"
|
||||
:description="validation.price ? validation.price.msg : null"
|
||||
v-model="partySet.price"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol s="12">
|
||||
<span>ترتیب نمایش در منو</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="err">
|
||||
<el-select v-model="partySet.index" filterable style="width: 100%;margin-top: 5px;">
|
||||
<el-option
|
||||
v-for="item in 1000"
|
||||
v-if="!partySets.filter(item2=>Number(item2.index) === item).length"
|
||||
:key="item + 202"
|
||||
:value="item"
|
||||
:label="item"/>
|
||||
</el-select>
|
||||
<p v-if="validation.index" class="text-danger" style="margin-top: 5px;">{{ validation.index.msg }}</p>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12" class="mt-3">
|
||||
<el-checkbox v-model="partySet.active">منو برای مشتریان نمایش داده شود</el-checkbox>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CForm>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol lg="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h3>تصویر: (اختیاری)</h3>
|
||||
<el-divider></el-divider>
|
||||
<img :src="partySet.image" alt="" style="width: 100%;max-width: 300px;display: block">
|
||||
<input type="file" ref="image" @change="imagePreview">
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axiosUploadProcess from "@/mixins/axiosUploadProcess"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
partySets: null,
|
||||
partySet: null,
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
mixins: [axiosUploadProcess],
|
||||
computed: {
|
||||
title() {
|
||||
return this.$route.params.food === 'new' ? 'افزودن منوی ویژه مهمانی' : 'مشاهده منوی ویژه'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
imagePreview(e) {
|
||||
this.partySet.image = URL.createObjectURL(e.target.files[0])
|
||||
},
|
||||
post() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('title', this.partySet.title)
|
||||
data.append('description', this.partySet.description)
|
||||
data.append('active', this.partySet.active)
|
||||
data.append('price', this.partySet.price)
|
||||
data.append('index', this.partySet.index)
|
||||
if (this.$refs.image.files[0]) data.append('image', this.$refs.image.files[0])
|
||||
|
||||
this.$axios.post(`/api/admin/partySet`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'منوی ویژه با موفقیت ایجاد شد.'
|
||||
})
|
||||
this.$router.push({name: 'admin-branch-party-sets'})
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append('title', this.partySet.title)
|
||||
data.append('description', this.partySet.description)
|
||||
data.append('active', this.partySet.active)
|
||||
data.append('price', this.partySet.price)
|
||||
data.append('index', this.partySet.index)
|
||||
if (this.$refs.image.files[0]) data.append('image', this.$refs.image.files[0])
|
||||
|
||||
this.$axios.put(`/api/admin/partySet/${this.partySet._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
this.$refs.image.value = null
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, error}) {
|
||||
try {
|
||||
const partySets = await $axios.get(`/api/public/partySets`)
|
||||
if (params.set !== 'new') {
|
||||
const partySet = await $axios.get(`/api/public/partySet/${params.set}`)
|
||||
return {
|
||||
partySets: partySets.data,
|
||||
partySet: partySet.data
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
partySets: partySets.data,
|
||||
partySet: {
|
||||
title: '',
|
||||
description: '',
|
||||
price: 0,
|
||||
active: true,
|
||||
image: '',
|
||||
index: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" :to="{name: 'admin-branch-party-sets-set',params:{set: 'new'}}" class="mr-auto">
|
||||
افزودن</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="partySets.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="عکس"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<img v-if="scope.row.image" :src="scope.row.image" alt="" style="width: 100px;">
|
||||
<i v-else class="fal fa-image-polaroid" style="font-size: 115px;"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="title"
|
||||
label="عنوان"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="قیمت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.price">{{ scope.row.price.toLocaleString() + ' ريال ' }}</span>
|
||||
<span v-else class="text-danger">بدون قیمت</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="وضعیت"
|
||||
width="">
|
||||
<template slot-scope="scope">
|
||||
<span class="text-success" v-if="scope.row.active">فعال</span>
|
||||
<span class="text-danger" v-else>غیر فعال</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="remove(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="success" variant="outline" :key="scope.row._id"
|
||||
:to="{name: 'admin-branch-party-sets-set',params: {set: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="partySets.totalDocs>20">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="partySets.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="partySets.page" :total="partySets.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست منوهای ویژه مهمانی',
|
||||
list_title: 'لیست',
|
||||
partySets: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-party-sets",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
remove(id) {
|
||||
this.$confirm('این مورد حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/partySet/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'منو با موفقیت حذف شد'
|
||||
})
|
||||
this.partySets.docs = this.partySets.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
|
||||
})
|
||||
} else console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, query, error}) {
|
||||
try {
|
||||
const partySets = await $axios.get(`/api/admin/partySets?page=${query.page || 1}`)
|
||||
return {
|
||||
partySets: partySets.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol sm="6">
|
||||
<div>از تاریخ:</div>
|
||||
<div class="mt-3"><date-picker type="datetime" v-model="startDate" clearable format="YYYY-MM-DD HH:mm" display-format="jYYYY-jMM-jDD HH:mm"/></div>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<div>تا تاریخ:</div>
|
||||
<div class="mt-3"><date-picker type="datetime" v-model="endDate" clearable format="YYYY-MM-DD HH:mm" display-format="jYYYY-jMM-jDD HH:mm"/></div>
|
||||
</CCol>
|
||||
<CCol sm="12" class="text-center mt-4">
|
||||
<CButton size="sm" color="success" class="mr-1" @click="getReports">گرفتن گزارش</CButton>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<!-- <div class="d-flex justify-content-center align-items-center">-->
|
||||
<!-- <span>از تاریخ: </span>-->
|
||||
<!-- <span><date-picker v-model="date" clearable format="YYYY-MM-DD" display-format="jYYYY-jMM-jDD"/></span>-->
|
||||
<!-- </div>-->
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol col="12" sm="6">
|
||||
<CCallout color="info">
|
||||
<small class="text-muted">جمع کل</small><br>
|
||||
<strong class="h4">{{ reports.total.toLocaleString() + ' ریال' }}</strong>
|
||||
</CCallout>
|
||||
</CCol>
|
||||
<CCol col="12" sm="6">
|
||||
<CCallout color="danger">
|
||||
<small class="text-muted">تعداد سفارشات</small><br>
|
||||
<strong class="h4">{{ reports.count }}</strong>
|
||||
</CCallout>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
<!-- <CCard>-->
|
||||
<!-- <CCardHeader>-->
|
||||
<!-- <strong>-->
|
||||
<!-- <span>نمودار تعداد سفارشات</span>-->
|
||||
<!-- </strong>-->
|
||||
<!-- </CCardHeader>-->
|
||||
<!-- <CCardBody>-->
|
||||
<!-- <canvas id="myChart" width="400" height="400"></canvas>-->
|
||||
<!-- </CCardBody>-->
|
||||
<!-- </CCard>-->
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol sm="6">
|
||||
<div class="mt-3">
|
||||
<span>
|
||||
<i class="fal fa-money-bill-wave"></i>
|
||||
جمع کل:
|
||||
</span>
|
||||
<span>{{reports.total.toLocaleString() + ' ریال'}}</span>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<span>
|
||||
<i class="fal fa-money-bill-wave"></i>
|
||||
جمع پرداخت آنلاین:
|
||||
</span>
|
||||
<span>{{reports.payOnline.toLocaleString() + ' ریال'}}</span>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<span>
|
||||
<i class="fal fa-money-bill-wave"></i>
|
||||
جمع هزینه ارسال:
|
||||
</span>
|
||||
<span>{{reports.routePrice.toLocaleString() + ' ریال'}}</span>
|
||||
</div>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<div class="mt-3">
|
||||
<span>
|
||||
<i class="fal fa-money-bill-wave"></i>
|
||||
جمع کل مبلغ استفاده شده کیف پول:
|
||||
</span>
|
||||
<span>{{reports.bagCost.toLocaleString() + ' ریال'}}</span>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<span>
|
||||
<i class="fal fa-money-bill-wave"></i>
|
||||
جمع امتیاز استفاده شده:
|
||||
</span>
|
||||
<span>{{reports.scorePoint}}</span>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<span>
|
||||
<i class="fal fa-money-bill-wave"></i>
|
||||
جمع ارزش امتیازات استفاده شده:
|
||||
</span>
|
||||
<span>{{reports.scoreCost.toLocaleString() + ' ریال'}}</span>
|
||||
</div>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment-jalaali'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'گزارشات',
|
||||
list_title: 'گزارش',
|
||||
// base data
|
||||
reports: null,
|
||||
startDate : '',
|
||||
endDate : '',
|
||||
// validation
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
jDate(date) {
|
||||
return moment(date, 'X').format('jYYYY/jMM/jDD')
|
||||
},
|
||||
getReports(){
|
||||
this.validation = {}
|
||||
const data = {
|
||||
startDate : this.startDate,
|
||||
endDate :this.endDate
|
||||
}
|
||||
|
||||
this.$axios.$post(`/api/admin/order/report`, data)
|
||||
.then(response => {
|
||||
this.reports = response
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response.status === 401) {
|
||||
return this.$message({
|
||||
type: 'error',
|
||||
message: 'لطفا دوباره وارد سیستم شوید.'
|
||||
})
|
||||
}
|
||||
if (err.response.status === 422) {
|
||||
this.validation = err.response.data.validation
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: err.response.data.message
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
// async mounted() {
|
||||
// const counts = {};
|
||||
// // this.customers.forEach(function (x) { counts[x.job] = (counts[x.job] || 0) + 1; });
|
||||
// let keys = [1,2,3,4,5,6,7];
|
||||
// let values = [10,15,4,5,68,15,1];
|
||||
//
|
||||
// const CHART_COLORS = {
|
||||
// red: 'rgb(255, 99, 132)',
|
||||
// orange: 'rgb(255, 159, 64)',
|
||||
// yellow: 'rgb(255, 205, 86)',
|
||||
// green: 'rgb(75, 192, 192)',
|
||||
// blue: 'rgb(54, 162, 235)',
|
||||
// purple: 'rgb(153, 102, 255)',
|
||||
// grey: 'rgb(201, 203, 207)'
|
||||
// };
|
||||
//
|
||||
// const ctx = document.getElementById('myChart');
|
||||
// const myChart = new Chart(ctx, {
|
||||
// type: 'line',
|
||||
// data: {
|
||||
// labels: keys,
|
||||
// datasets: [{
|
||||
// // label: '# of Votes',
|
||||
// data: values,
|
||||
// borderColor: 'rgb(54, 162, 235)',
|
||||
// fill: false,
|
||||
// borderWidth: 2
|
||||
// }]
|
||||
// },
|
||||
// options: {
|
||||
// responsive: true,
|
||||
// legend: {
|
||||
// position: 'top',
|
||||
// },
|
||||
// scales: {
|
||||
// y: {
|
||||
// beginAtZero: true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, query, error, params}) {
|
||||
try {
|
||||
const reports = await $axios.$post(`/api/admin/order/report/${params?.branch}`)
|
||||
return {
|
||||
reports
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.el-button:focus {
|
||||
outline-color: #39f !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,508 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" class="mr-auto" @click="addInfo">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CCol>
|
||||
<!-- <h5 style="margin-bottom: 16px"></h5>-->
|
||||
<CCol sm="12">
|
||||
<el-checkbox v-model="storeInfo.useSpecialMenu" label="نمایش منو سرآشپز"/>
|
||||
</CCol>
|
||||
<CCol class="mt-2" sm="6">
|
||||
<CInput
|
||||
v-if="$auth.user.permissions.includes('development')"
|
||||
:class="validation.updateApp ? 'err' : null"
|
||||
class="input-direction"
|
||||
label="ورژن اپلیکیشن"
|
||||
:description="validation.updateApp ? validation.updateApp.msg : null"
|
||||
v-model="storeInfo.updateApp"
|
||||
/>
|
||||
</CCol>
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CCol>
|
||||
<h5 style="margin-bottom: 16px">پیام مدیر</h5>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.message ? 'err' : null"
|
||||
label="پیام روز"
|
||||
:description="validation.message ? validation.message.msg : null"
|
||||
v-model="storeInfo.message"
|
||||
/>
|
||||
</CCol>
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CCol>
|
||||
<h5 style="margin-bottom: 16px">اطلاعات عمومی</h5>
|
||||
<CCol sm="12">
|
||||
<CTextarea
|
||||
:class="validation.caption ? 'err' : null"
|
||||
label="توضیحات"
|
||||
:description="validation.caption ? validation.caption.msg : null"
|
||||
v-model="storeInfo.caption"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
class="input-direction"
|
||||
:class="validation.email ? 'err' : null"
|
||||
label="ایمیل"
|
||||
:description="validation.email ? validation.email.msg : null"
|
||||
v-model="storeInfo.email"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
class="input-direction"
|
||||
:class="validation.tel ? 'err' : null"
|
||||
label="تلفن"
|
||||
:description="validation.tel ? validation.tel.msg : null"
|
||||
v-model="storeInfo.tel"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.address ? 'err' : null"
|
||||
label="آدرس"
|
||||
:description="validation.address ? validation.address.msg : null"
|
||||
v-model="storeInfo.address"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CCol>
|
||||
<h5 style="margin-bottom: 16px">شبکه های اجتماعی</h5>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
class="input-direction"
|
||||
:class="validation.socials ? 'err' : null"
|
||||
label="واتساپ"
|
||||
:description="validation.socials ? validation.socials.msg : null"
|
||||
v-model="storeInfo.socials.whatsaap"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
class="input-direction"
|
||||
:class="validation.socials ? 'err' : null"
|
||||
label="تویتر"
|
||||
:description="validation.socials ? validation.socials.msg : null"
|
||||
v-model="storeInfo.socials.twitter"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
class="input-direction"
|
||||
:class="validation.socials ? 'err' : null"
|
||||
label="فیس بوک"
|
||||
:description="validation.socials ? validation.socials.msg : null"
|
||||
v-model="storeInfo.socials.facebook"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.socials ? 'err' : null"
|
||||
class="input-direction"
|
||||
label="اینستاگرام"
|
||||
:description="validation.socials ? validation.socials.msg : null"
|
||||
v-model="storeInfo.socials.instagram"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.socials ? 'err' : null"
|
||||
class="input-direction"
|
||||
label="گوگل پلاس"
|
||||
:description="validation.socials ? validation.socials.msg : null"
|
||||
v-model="storeInfo.socials.googlePlus"
|
||||
/>
|
||||
</CCol>
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h5 style="margin-bottom: 16px">تنظیمات هزینه ارسال و مالیات</h5>
|
||||
<CCol>
|
||||
<CCol sm="6">
|
||||
<el-checkbox v-model="storeInfo.tax" label="گرفتن مالیات از مشتری"/>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<el-checkbox v-model="storeInfo.shippingType" label="هزینه ارسال ثابت باشد"/>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<CInput
|
||||
:class="validation.socials ? 'err' : null"
|
||||
label="هزینه ارسال به ریال(به ازای هر کیلومتر در صورت ثابت نبودن)"
|
||||
placeholder=""
|
||||
:description="validation.shippingCost ? validation.shippingCost.msg : null"
|
||||
v-model="storeInfo.shippingCost"
|
||||
/>
|
||||
</CCol>
|
||||
<el-divider/>
|
||||
<CCol sm="6">
|
||||
<CInput
|
||||
:class="validation.limitPrice ? 'err' : null"
|
||||
label="حداقل مبلغ خرید(ریال)"
|
||||
placeholder=""
|
||||
:description="validation.limitPrice ? validation.limitPrice.msg : null"
|
||||
v-model="storeInfo.limitPrice"
|
||||
/>
|
||||
</CCol>
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h5 style="margin-bottom: 16px">تنظیمات امتیازات</h5>
|
||||
<CCol>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<el-checkbox class="mb-4" v-model="storeInfo.usePointWhenPay" label="اجازه استفاده از امتیاز هنگام پرداخت"/>
|
||||
</CCol>
|
||||
<CCol sm="12" class="mb-3">
|
||||
<span>به ازای هر</span>
|
||||
<CInput
|
||||
type="number"
|
||||
style="display: inline-block"
|
||||
:class="validation.totalPricePoint ? 'err' : null"
|
||||
placeholder="قیمت به ریال وارد شود"
|
||||
:description="validation.totalPricePoint ? validation.totalPricePoint.msg : null"
|
||||
v-model="storeInfo.totalPricePoint"
|
||||
/>
|
||||
<span><b>ریال</b> خرید مقدار</span>
|
||||
<CInput
|
||||
type="number"
|
||||
style="display: inline-block"
|
||||
:class="validation.pointForBuy ? 'err' : null"
|
||||
placeholder=""
|
||||
:description="validation.pointForBuy ? validation.pointForBuy.msg : null"
|
||||
v-model="storeInfo.pointForBuy"
|
||||
/>
|
||||
<span>امتیاز به مشتری داده شود</span>
|
||||
</CCol>
|
||||
<CCol sm="12" class="mb-3">
|
||||
<span>هر</span>
|
||||
<CInput
|
||||
type="number"
|
||||
style="display: inline-block"
|
||||
:class="validation.pointForChange ? 'err' : null"
|
||||
placeholder=""
|
||||
:description="validation.pointForChange ? validation.pointForChange.msg : null"
|
||||
v-model="storeInfo.pointForChange"
|
||||
/>
|
||||
<span>امتیاز برابر با</span>
|
||||
<CInput
|
||||
type="number"
|
||||
style="display: inline-block"
|
||||
:class="validation.priceForChange ? 'err' : null"
|
||||
placeholder=""
|
||||
:description="validation.priceForChange ? validation.priceForChange.msg : null"
|
||||
v-model="storeInfo.priceForChange"
|
||||
/>
|
||||
<span><b>ریال</b> می باشد</span>
|
||||
</CCol>
|
||||
<el-divider/>
|
||||
<CCol sm="6">
|
||||
<CInput
|
||||
:class="validation.userRegistrationScore ? 'err' : null"
|
||||
label="امتیاز ثبت نام"
|
||||
placeholder=""
|
||||
:description="validation.userRegistrationScore ? validation.userRegistrationScore.msg : null"
|
||||
v-model="storeInfo.userRegistrationScore"
|
||||
/>
|
||||
<!-- <CInput-->
|
||||
<!-- :class="validation.userEmailVerifyScore ? 'err' : null"-->
|
||||
<!-- label="امتیاز وارد کردن ایمیل"-->
|
||||
<!-- placeholder=""-->
|
||||
<!-- :description="validation.userEmailVerifyScore ? validation.userEmailVerifyScore.msg : null"-->
|
||||
<!-- v-model="storeInfo.userEmailVerifyScore"-->
|
||||
<!-- />-->
|
||||
<CInput
|
||||
:class="validation.pointBirthDate ? 'err' : null"
|
||||
label="امتیاز تاریخ تولد"
|
||||
placeholder=""
|
||||
:description="validation.pointBirthDate ? validation.pointBirthDate.msg : null"
|
||||
v-model="storeInfo.pointBirthDate"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<CInput
|
||||
:class="validation.pointMarriageDate ? 'err' : null"
|
||||
label="امتیاز تاریخ ازدواج"
|
||||
placeholder=""
|
||||
:description="validation.pointMarriageDate ? validation.pointMarriageDate.msg : null"
|
||||
v-model="storeInfo.pointMarriageDate"
|
||||
/>
|
||||
<CInput
|
||||
:class="validation.invitePoint ? 'err' : null"
|
||||
label="امتیاز دعوت کردن"
|
||||
placeholder=""
|
||||
:description="validation.invitePoint ? validation.invitePoint.msg : null"
|
||||
v-model="storeInfo.invitePoint"
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h5 style="margin-bottom: 16px">تنظیمات ساعت کار رستوران</h5>
|
||||
<CCol>
|
||||
<CRow>
|
||||
<CCol sm="6">
|
||||
<el-checkbox v-model="storeInfo.closeStore" label="فروشگاه تعطیل است"/>
|
||||
</CCol>
|
||||
<CRow v-if="!storeInfo.closeStore" class="mb-5">
|
||||
<CCol sm="6">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>ساعت شروع</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<date-picker type="time" format="HH:mm" display-format="HH:mm" clearable v-model="storeInfo.firstStartTime"></date-picker>
|
||||
<p class="text-danger" v-if="validation.firstStartTime">
|
||||
{{ validation.firstStartTime.msg }}
|
||||
</p>
|
||||
</CCol>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>ساعت پایان</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<date-picker type="time" format="HH:mm" display-format="HH:mm" clearable v-model="storeInfo.firstEndTime"></date-picker>
|
||||
<p class="text-danger" v-if="validation.firstEndTime">
|
||||
{{ validation.firstEndTime.msg }}
|
||||
</p>
|
||||
</CCol>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow v-if="!storeInfo.closeStore">
|
||||
<el-divider/>
|
||||
<CCol sm="6">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>ساعت شروع</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<date-picker type="time" format="HH:mm" display-format="HH:mm" clearable v-model="storeInfo.secondStartTime"></date-picker>
|
||||
<p class="text-danger" v-if="validation.secondStartTime">
|
||||
{{ validation.secondStartTime.msg }}
|
||||
</p>
|
||||
</CCol>
|
||||
</CCol>
|
||||
<CCol sm="6">
|
||||
<CCol col="md-3" class="mb-2">
|
||||
<span>ساعت پایان</span>
|
||||
</CCol>
|
||||
<CCol col="md-9">
|
||||
<date-picker type="time" format="HH:mm" display-format="HH:mm" clearable v-model="storeInfo.secondEndTime"></date-picker>
|
||||
<p class="text-danger" v-if="validation.secondEndTime">
|
||||
{{ validation.secondEndTime.msg }}
|
||||
</p>
|
||||
</CCol>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CRow>
|
||||
</CCol>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CRow>
|
||||
<CRow>
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<h5>مشخص کردن مکان رستوران روی نقشه</h5>
|
||||
</CCardHeader>
|
||||
<CCardBody class="text-center">
|
||||
<template>
|
||||
<no-ssr>
|
||||
<mapir class="d-inline-flex" id="map" :min-zoom="12" :max-zoom="18" :zoom="15" logo-position="top-left" :center="storeInfo.location.coordinates || center" @click="mapOnClick" :apiKey="apiKey">
|
||||
<mapNavigationControl position="top-right"/>
|
||||
<mapGeolocateControl position="top-right"/>
|
||||
<mapMarker
|
||||
:coordinates.sync="storeInfo.location.coordinates || center"
|
||||
color="red"
|
||||
@click="markerOnClick"
|
||||
:draggable="true"
|
||||
@dragend="getlatLng"
|
||||
/>
|
||||
</mapir>
|
||||
</no-ssr>
|
||||
</template>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
</CRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment-jalaali'
|
||||
|
||||
let mapirVue = {}
|
||||
if (process.client)
|
||||
mapirVue = require('mapir-vue')
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'mapir': mapirVue.mapir,
|
||||
'mapMarker': mapirVue.mapMarker,
|
||||
'mapNavigationControl': mapirVue.mapNavigationControl,
|
||||
'mapGeolocateControl': mapirVue.mapGeolocateControl,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
apiKey: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIn0.eyJhdWQiOiIxNDk3OSIsImp0aSI6ImRiYjIwMmRhYzAxYzFjNzgwYjgxNWQyZDgyMWNmNmY1Njk0MThhMGE3N2Q1M2Y0OTZkYzQzYTgxMmNmN2U3ZWJjNzI5MjY5YjkxMjA4MTYyIiwiaWF0IjoxNjI3MzI2Mzc0LCJuYmYiOjE2MjczMjYzNzQsImV4cCI6MTYyOTkxODM3NCwic3ViIjoiIiwic2NvcGVzIjpbImJhc2ljIl19.hyKNSy4fmPps6yIdm33Wof-mES9ujh5lmI3VFWyecbkNCm9ATPwsZ9s53A3a1wPJmHfLBXpCcob5NGL-GjZlVfqfRBiReRMr_iniCjUOnqENfFwVEJutxI-xrzVe7PZzOgx1Vr6WwSUHvQ36eJSS1lBlHlqCgwRbkG0hs4YdZsKhzhfYdlAluNw9djjUAMbRWZVL0EluP9CYko4w8tB0KHUZMZYGQcevCfb_3OU9ygHo7B--Z5aTPfm7IK4eP0gHsZ_t857B3tu3ZJB1mkgxc2R9gZUflKqj1ZqkYiR0uMGP-571enXh6pYQLXL2k-gOxLIedCaE6XytxVXhENnotA',
|
||||
title: 'اطلاعات فروشگاه',
|
||||
list_title: 'لیست',
|
||||
// base data
|
||||
storeInfo: null,
|
||||
center: [49.6848857, 34.0821617],
|
||||
// validation
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
mapOnClick(e) {
|
||||
this.storeInfo.location = {
|
||||
type: 'Point',
|
||||
coordinates: [e.actualEvent.lngLat.lng , e.actualEvent.lngLat.lat]
|
||||
}
|
||||
},
|
||||
markerOnClick(e) {
|
||||
|
||||
},
|
||||
getlatLng(e) {
|
||||
|
||||
},
|
||||
addInfo() {
|
||||
this.validation = {}
|
||||
this.storeInfo.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
this.$axios.post(`/api/admin/store/${this.$route.params.branch}`, this.storeInfo)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'تغییرات با موفقیت انجام شد'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.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 === 500) {
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "مشکلی در ارسال درخواست پیش آمده",
|
||||
});
|
||||
}
|
||||
if (err.response.status === 422){
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'پارامترها را بررسی کنید'
|
||||
})
|
||||
this.validation = err.response.data.validation;
|
||||
} else console.log(err.response.data);
|
||||
});
|
||||
},
|
||||
jDate(date) {
|
||||
return moment(date, 'X').format('jYYYY/jMM/jDD')
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, error , params}) {
|
||||
try {
|
||||
const store = await $axios.get(`/api/admin/store/${params.branch}`)
|
||||
return {
|
||||
storeInfo: store.data
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.el-button:focus {
|
||||
outline-color: #39f !important;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100vh;
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
.holder-logo{
|
||||
left: 0;
|
||||
}
|
||||
.mapboxgl-ctrl-attrib-button{
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,382 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="primary" class="mr-auto" :to="{name: 'admin-branch-users'}">برگشت به صفحه قبل</CButton>
|
||||
<CButton v-if="$route.params.profile === 'new'" size="sm" color="success" class="mr-1" @click="post">افزودن</CButton>
|
||||
<CButton v-else size="sm" color="success" class="mr-1" @click="update">بروزرسانی</CButton>
|
||||
</CustomSubHeader>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<CRow>
|
||||
<CCol lg="6">
|
||||
<CForm>
|
||||
<template v-if="$route.params.profile !== 'new'">
|
||||
<h4>مشخصات کاربر</h4>
|
||||
<el-divider/>
|
||||
</template>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.first_name ? 'err' : null"
|
||||
label="نام"
|
||||
:description="validation.first_name ? validation.first_name.msg : null"
|
||||
v-model="user.first_name"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.last_name ? 'err' : null"
|
||||
label="نام خانوادگی"
|
||||
:description="validation.last_name ? validation.last_name.msg : null"
|
||||
v-model="user.last_name"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.username ? 'err' : null"
|
||||
label="نام کاربری"
|
||||
:description="validation.username ? validation.username.msg : null"
|
||||
v-model="user.username"
|
||||
/>
|
||||
<p class="form-err" v-if="validation.username">{{ validation.username.msg }}</p>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.mobile_number ? 'err' : null"
|
||||
label="تلفن همراه"
|
||||
v-model="user.mobile_number"
|
||||
:description="validation.mobile_number ? validation.mobile_number.msg : null"
|
||||
placeholder="اختیاری"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.email ? 'err' : null"
|
||||
label="ایمیل"
|
||||
v-model="user.email"
|
||||
:description="validation.email ? validation.email.msg : null"
|
||||
placeholder="اختیاری"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<template v-if="$route.params.profile === 'new'">
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.password ? 'err' : null"
|
||||
label="کلمه عبور"
|
||||
type="password"
|
||||
:description="validation.password ? validation.password.msg : null"
|
||||
v-model="user.password"
|
||||
/>
|
||||
</CCol>
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.password_confirmation ? 'err' : null"
|
||||
label="تکرار کلمه عبور"
|
||||
type="password"
|
||||
:description="validation.password_confirmation ? validation.password_confirmation.msg : null"
|
||||
v-model="user.password_confirmation"
|
||||
/>
|
||||
</CCol>
|
||||
</template>
|
||||
</CRow>
|
||||
<el-divider/>
|
||||
<h6>انتخاب شعبه قابل دسترسی</h6>
|
||||
<el-select v-model="user.branches" multiple placeholder="انتخاب کنید" style="width: 100%;">
|
||||
<el-option v-for="item in branches" :key="item._id" :label="item.title" :value="item._id"/>
|
||||
</el-select>
|
||||
<p style="margin-top : 5px !important ; color : red" class="form-err" v-if="validation.branches">{{ validation.branches.msg }}</p>
|
||||
<el-divider/>
|
||||
<h6>دسترسی های کاربر</h6>
|
||||
<div class="user-permissions">
|
||||
<el-tag
|
||||
class="ml-2 mb-2"
|
||||
style="cursor: pointer"
|
||||
v-for="(item,index) in user.permissions"
|
||||
:key="index + Math.random() + 1"
|
||||
closable
|
||||
disable-transitions
|
||||
@close="removePermission(item)"
|
||||
>{{ getPermissionName(item) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</CForm>
|
||||
</CCol>
|
||||
<CCol lg="6">
|
||||
<CForm>
|
||||
<CRow>
|
||||
<CCol sm="12">
|
||||
<h4>عکس پروفایل</h4>
|
||||
<el-divider/>
|
||||
<CCol>
|
||||
<img :src="user.profile_pic" style="width: 100%;max-width: 250px;" alt="">
|
||||
</CCol>
|
||||
<input type="file" ref="profile_pic" @change="imagePreview">
|
||||
<p style="margin-top : 5px !important ;" class="form-err" v-if="validation.profile_pic">{{ validation.profile_pic.msg }}</p>
|
||||
<p class="mt-3 text-muted">عکس 500*500 باشد. در غیر این صورت اتوماتیک بریده می شود.</p>
|
||||
<CCol>
|
||||
</CCol>
|
||||
<p style="margin-top : 0px !important ; " class="form-err" v-if="validation.password_confirmation">{{ validation.password_confirmation.msg }}</p>
|
||||
</CCol>
|
||||
<template v-if="$route.params.profile !== 'new'">
|
||||
<CCol sm="12" class="mt-5">
|
||||
<h4>تغییر کلمه عبور</h4>
|
||||
<el-divider/>
|
||||
<CInput
|
||||
:class="validation.password ? 'err' : null"
|
||||
label="کلمه عبور"
|
||||
type="password"
|
||||
:description="validation.password ? validation.password.msg : null"
|
||||
v-model="newPass.password"
|
||||
/>
|
||||
</CCol>
|
||||
|
||||
<CCol sm="12">
|
||||
<CInput
|
||||
:class="validation.password_confirmation ? 'err' : null"
|
||||
label="تکرار کلمه عبور"
|
||||
type="password"
|
||||
:description="validation.password_confirmation ? validation.password_confirmation.msg : null"
|
||||
v-model="newPass.password_confirmation"
|
||||
/>
|
||||
|
||||
<CButton size="sm" color="success" class="mr-1 mt-3" @click="updatePassword">تغییر کلمه عبور</CButton>
|
||||
</CCol>
|
||||
</template>
|
||||
</CRow>
|
||||
|
||||
</CForm>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
<CCard>
|
||||
<CCardBody>
|
||||
<h6>لیست کل دسترسی ها</h6>
|
||||
<div class="permissions">
|
||||
<el-tag
|
||||
class="ml-2 mb-2"
|
||||
style="cursor: pointer"
|
||||
v-for="(item,index) in permissions"
|
||||
:key="index + Math.random() + 2"
|
||||
:type="hasPermission(item.value) ? 'success' : 'primary'"
|
||||
disable-transitions
|
||||
@click="addPermission(item.value)"
|
||||
>{{ item.name }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
|
||||
</CCol>
|
||||
|
||||
</CRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axiosUploadProcess from "@/mixins/axiosUploadProcess"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
user: null,
|
||||
permissions: null,
|
||||
branches: null,
|
||||
newPass: {
|
||||
password: '',
|
||||
password_confirmation: ''
|
||||
},
|
||||
validation: {}
|
||||
}
|
||||
},
|
||||
mixins: [axiosUploadProcess],
|
||||
computed: {
|
||||
title() {
|
||||
return this.$route.params.profile === 'new' ? 'افزودن کاربر' : 'مشاهده پروفایل کاربر'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPermissionName(value) {
|
||||
return this.permissions.filter(item => item.value === value)[0].name
|
||||
},
|
||||
addPermission(val) {
|
||||
if (!this.user.permissions.includes(val)) this.user.permissions.push(val)
|
||||
else this.$message({
|
||||
type: 'warning',
|
||||
message: 'کاربر از قبل این دسترسی را دارد'
|
||||
})
|
||||
},
|
||||
removePermission(val) {
|
||||
this.user.permissions = this.user.permissions.filter(item => item !== val)
|
||||
},
|
||||
hasPermission(val) {
|
||||
return this.user.permissions.includes(val)
|
||||
},
|
||||
imagePreview(e) {
|
||||
this.user.profile_pic = URL.createObjectURL(e.target.files[0])
|
||||
},
|
||||
post() {
|
||||
this.validation = {}
|
||||
|
||||
const data = new FormData()
|
||||
data.append("first_name", this.user.first_name)
|
||||
data.append("last_name", this.user.last_name)
|
||||
data.append("mobile_number", this.user.mobile_number)
|
||||
data.append("email", this.user.email)
|
||||
data.append("username", this.user.username)
|
||||
data.append("permissions", JSON.stringify(this.user.permissions))
|
||||
data.append("branches", JSON.stringify(this.user.branches))
|
||||
data.append("password", this.user.password)
|
||||
data.append("password_confirmation", this.user.password_confirmation)
|
||||
if (this.$refs.profile_pic.files[0]) data.append("profile_pic", this.$refs.profile_pic.files[0])
|
||||
|
||||
|
||||
this.$axios.post(`/api/admin/admin`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'کاربر با موفقیت ایجاد شد.'
|
||||
})
|
||||
this.$router.push({name: 'admin-branch-users'})
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.validation = {}
|
||||
const data = new FormData()
|
||||
data.append("first_name", this.user.first_name)
|
||||
data.append("last_name", this.user.last_name)
|
||||
data.append("mobile_number", this.user.mobile_number)
|
||||
data.append("email", this.user.email)
|
||||
data.append("username", this.user.username)
|
||||
data.append("permissions", JSON.stringify(this.user.permissions))
|
||||
data.append("branches", JSON.stringify(this.user.branches))
|
||||
data.append("password", this.user.password)
|
||||
data.append("password_confirmation", this.user.password_confirmation)
|
||||
if (this.$refs.profile_pic.files[0]) data.append("profile_pic", this.$refs.profile_pic.files[0])
|
||||
|
||||
this.$axios.put(`/api/admin/admin/${this.user._id}`, data, this.axiosConfig)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'اطلاعات بروزرسانی شد.'
|
||||
})
|
||||
this.$nuxt.refresh()
|
||||
})
|
||||
.catch(err => {
|
||||
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)
|
||||
})
|
||||
},
|
||||
updatePassword() {
|
||||
this.validation = {}
|
||||
this.$axios.put(`/api/admin/changeAdminPasswordByAdmin/${this.user._id}`, this.newPass)
|
||||
.then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'کلمه عبور بروزرسانی شد.'
|
||||
})
|
||||
this.newPass = {
|
||||
password: '',
|
||||
password_confirmation: ''
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
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, params, error}) {
|
||||
try {
|
||||
const permissions = await $axios.get('/api/admin/permissions')
|
||||
const branches = await $axios.$get('/api/admin/store/getAll')
|
||||
if (params.profile !== 'new') {
|
||||
const user = await $axios.get(`/api/admin/admin/${params.profile}`)
|
||||
return {
|
||||
permissions: permissions.data,
|
||||
user: user.data,
|
||||
branches
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
permissions: permissions.data,
|
||||
branches,
|
||||
user: {
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
mobile_number: '',
|
||||
email: '',
|
||||
username: '',
|
||||
password: '',
|
||||
password_confirmation: '',
|
||||
profile_pic: '',
|
||||
permissions: [],
|
||||
branches: []
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: "لطفا دوباره وارد سیستم شوید.",
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 403) {
|
||||
error({
|
||||
status: 403,
|
||||
message: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
if (e?.response?.status === 500) {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات پیش آمده",
|
||||
});
|
||||
} else
|
||||
error({
|
||||
status: 404,
|
||||
message: "اطلاعات مورد نظر پیدا نشد",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div>
|
||||
<CustomSubHeader>
|
||||
<CBreadcrumb class="border-0 mb-0">{{ title }}</CBreadcrumb>
|
||||
<CButton size="sm" color="success" :to="{name: 'admin-branch-users-profile',params:{profile: 'new'}}"
|
||||
class="mr-auto">افزودن</CButton>
|
||||
</CustomSubHeader>
|
||||
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<slot name="header">
|
||||
<i class="fal fa-bars"></i>
|
||||
<span>{{ list_title }}</span>
|
||||
</slot>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<el-table
|
||||
:data="users.docs"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="#">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="first_name"
|
||||
label="نام"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="last_name"
|
||||
label="نام خانوادگی"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="username"
|
||||
label="نام کاربری"
|
||||
width="">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="ویرایش"
|
||||
width="110"
|
||||
align="center">
|
||||
<template slot-scope="scope">
|
||||
<CButton color="danger" variant="outline" :key="scope.row._id + Math.random()" @click="deleteUser(scope.row._id)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</CButton>
|
||||
<CButton color="success" variant="outline" :key="scope.row._id"
|
||||
:to="{name: 'admin-branch-users-profile',params: {profile: scope.row._id}}">
|
||||
<i class="far fa-eye"></i>
|
||||
</CButton>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
<CCard class="col" v-if="users.totalDocs>5">
|
||||
<CRow alignHorizontal="center" style="padding : 10px">
|
||||
<el-pagination :hide-on-single-page="true" layout="prev, pager, next" :page-size="users.limit"
|
||||
@current-change="handleCurrentChange" :current-page.sync="users.page" :total="users.totalDocs">
|
||||
</el-pagination>
|
||||
</CRow>
|
||||
</CCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'لیست کاربران',
|
||||
list_title: 'لیست',
|
||||
users: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageQuery() {
|
||||
return this.$route.query.page;
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
pageQuery(newPage, oldPage) {
|
||||
this.$nuxt.refresh();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCurrentChange(page) {
|
||||
// if (!_.isEmpty(this.search)) {
|
||||
// this.handleSearch(page);
|
||||
// } else {
|
||||
this.$router.push({
|
||||
name: "admin-branch-users",
|
||||
query: {
|
||||
page: page
|
||||
}
|
||||
});
|
||||
// }
|
||||
},
|
||||
deleteUser(id) {
|
||||
this.$confirm('کاربر حذف شود؟', 'هشدار', {
|
||||
confirmButtonText: 'بله',
|
||||
cancelButtonText: 'لغو',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.$axios.delete(`/api/admin/admin/${id}`)
|
||||
.then(res => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'کاربر با موفقیت حذف شد'
|
||||
})
|
||||
this.users.docs = this.users.docs.filter(item => item._id !== id)
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response.status === 401) {
|
||||
return this.$message({
|
||||
type: 'error',
|
||||
message: 'لطفا دوباره وارد سیستم شوید.'
|
||||
})
|
||||
}
|
||||
console.log(err.response.data)
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: 'عملیات لغو شد'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
},
|
||||
layout: 'admin',
|
||||
async asyncData({$axios, query , error , params}) {
|
||||
try {
|
||||
const users = await $axios.get(`/api/admin/admins/${params?.branch}?page=${query.page}`)
|
||||
return {
|
||||
users: users.data
|
||||
}
|
||||
} catch (e) {
|
||||
if (e?.response?.status === 401) {
|
||||
error({
|
||||
status: 401,
|
||||
message: 'شما اجازه دسترسی به این صفحه را ندارید لطفا دوباره وارد شوید'
|
||||
})
|
||||
} else {
|
||||
error({
|
||||
status: 500,
|
||||
message: "مشکلی در گرفتن اطلاعات بوجود آمده است",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user