|
|
@@ -23,6 +23,8 @@
|
|
|
label="آزمون" />
|
|
|
<q-tab name="transcriptSheetHistory"
|
|
|
label="تاریخچه کارنامه" />
|
|
|
+ <q-tab name="subscriptions"
|
|
|
+ label="اطلاع رسانی" />
|
|
|
</q-tabs>
|
|
|
<q-separator />
|
|
|
<q-tab-panels v-if="mounted"
|
|
|
@@ -187,8 +189,134 @@
|
|
|
</template>
|
|
|
</entity-index>
|
|
|
</q-tab-panel>
|
|
|
+ <q-tab-panel name="subscriptions"
|
|
|
+ class="q-pa-none">
|
|
|
+ <entity-index v-if="mounted"
|
|
|
+ ref="subscriptionsEntityIndex"
|
|
|
+ v-model:value="subscriptionsFilterInputs"
|
|
|
+ title="لیست دنبال کنندگان"
|
|
|
+ :api="subscriptionsApi"
|
|
|
+ :table="subscriptionsTable"
|
|
|
+ :table-keys="subscriptionsTableKeys"
|
|
|
+ :show-reload-button="false"
|
|
|
+ :show-search-button="false"
|
|
|
+ :show-expand-button="false">
|
|
|
+ <template #toolbar>
|
|
|
+ <div class="flex flex-nowrap justify-end">
|
|
|
+ <q-btn class="q-ml-sm"
|
|
|
+ color="primary"
|
|
|
+ outline
|
|
|
+ :loading="exportReportLoading"
|
|
|
+ @click="getSubscriptionsListExcel">
|
|
|
+ خروجی اکسل
|
|
|
+ </q-btn>
|
|
|
+ <q-btn class="q-ml-sm"
|
|
|
+ color="primary"
|
|
|
+ label="ارسال پیام"
|
|
|
+ @click="showAlertDialog = true" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #before-index-table>
|
|
|
+ <div class="flex flex-nowrap justify-end"
|
|
|
+ style="margin-bottom: 16px; margin-left: 16px">
|
|
|
+ <q-btn color="red"
|
|
|
+ outline
|
|
|
+ :loading="deleteAllLoading"
|
|
|
+ @click="confirmRemoveAllDialog = true">
|
|
|
+ حذف همه دنبال کنندگان
|
|
|
+ </q-btn>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #after-index-table>
|
|
|
+ <q-separator class="q-my-lg" />
|
|
|
+ </template>
|
|
|
+ <template #entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
|
|
|
+ <template v-if="inputData.col.name === 'actions'">
|
|
|
+ <div class="q-gutter-md">
|
|
|
+ <div class="action-column-entity-index">
|
|
|
+ <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ {{ inputData.col.value }}
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </entity-index>
|
|
|
+ </q-tab-panel>
|
|
|
</q-tab-panels>
|
|
|
- </q-card>
|
|
|
+ </q-card> <!-- دیالوگ -->
|
|
|
+ <q-dialog v-model="showAlertDialog">
|
|
|
+ <q-card class="my-dialog-card q-pa-md">
|
|
|
+ <q-card-section class="text-center">
|
|
|
+ <div class="text-h6">ارسال پیام</div>
|
|
|
+ </q-card-section>
|
|
|
+ <q-card-section>
|
|
|
+ <q-input v-model="alertMessageText"
|
|
|
+ type="textarea"
|
|
|
+ label="متن پیام خود را وارد کنید"
|
|
|
+ autogrow
|
|
|
+ :disable="sendingAlertConfirmation"
|
|
|
+ dense />
|
|
|
+ </q-card-section>
|
|
|
+
|
|
|
+ <q-separator />
|
|
|
+
|
|
|
+ <q-card-actions class="q-gutter-sm"
|
|
|
+ align="center">
|
|
|
+ <template v-if="!sendingAlertConfirmation">
|
|
|
+ <q-btn v-close-popup
|
|
|
+ class="full-width-button"
|
|
|
+ flat
|
|
|
+ label="انصراف"
|
|
|
+ color="primary" />
|
|
|
+ <!-- مرحله اول: دکمه ارسال -->
|
|
|
+ <q-btn v-if="!sendingAlertConfirmation"
|
|
|
+ class="full-width-button"
|
|
|
+ label="ادامه به ارسال"
|
|
|
+ color="primary"
|
|
|
+ :disable="!alertMessageText.trim()"
|
|
|
+ @click="sendingAlertConfirmation = true" />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else>
|
|
|
+ <!-- مرحله دوم: تأیید نهایی -->
|
|
|
+ <div class="text-body2 q-mb-md">آیا مطمئن هستید که میخواهید پیام را ارسال کنید؟</div>
|
|
|
+ <q-btn class="full-width-button"
|
|
|
+ flat
|
|
|
+ color="grey"
|
|
|
+ label="خیر"
|
|
|
+ @click="sendingAlertConfirmation = false" />
|
|
|
+ <q-btn class="full-width-button"
|
|
|
+ color="red"
|
|
|
+ label="بله، ارسال کن"
|
|
|
+ :loading="sendingAlertMessage"
|
|
|
+ @click="sendAlertMessage" />
|
|
|
+ </template>
|
|
|
+ </q-card-actions>
|
|
|
+ </q-card>
|
|
|
+ </q-dialog>
|
|
|
+ <q-dialog v-model="confirmRemoveAllDialog"
|
|
|
+ persistent>
|
|
|
+ <q-card>
|
|
|
+ <q-card-section class="row items-center">
|
|
|
+ <q-icon name="warning"
|
|
|
+ color="primary"
|
|
|
+ size="md" />
|
|
|
+ <span class="q-ml-sm">{{ confirmRemoveAllMessage }}</span>
|
|
|
+ </q-card-section>
|
|
|
+ <q-card-actions align="right">
|
|
|
+ <q-btn flat
|
|
|
+ label="انصراف"
|
|
|
+ color="primary"
|
|
|
+ @click="confirmRemoveAllDialog = false" />
|
|
|
+ <q-btn flat
|
|
|
+ label="تایید"
|
|
|
+ color="primary"
|
|
|
+ @click="deleteAllSubscriptions" />
|
|
|
+ </q-card-actions>
|
|
|
+ </q-card>
|
|
|
+ </q-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
@@ -202,6 +330,7 @@ import PostRequisites from 'src/components/Control/PostRequisites.vue'
|
|
|
import FormBuilderInputEditor from 'src/components/FormBuilderCustumComponents/FormBuilderInputEditor.vue'
|
|
|
import { FormBuilderAssist } from 'quasar-form-builder'
|
|
|
import BtnControl from 'src/components/Control/btn.vue'
|
|
|
+import Assist from 'assets/js/Assist'
|
|
|
|
|
|
const PostRequisitesComp = shallowRef(PostRequisites)
|
|
|
const FormBuilderInputEditorComp = shallowRef(FormBuilderInputEditor)
|
|
|
@@ -219,7 +348,15 @@ export default {
|
|
|
return {
|
|
|
tab: 'UnitInfo',
|
|
|
mounted: false,
|
|
|
+ exportReportLoading: false,
|
|
|
+ deleteAllLoading: false,
|
|
|
+ showAlertDialog: false,
|
|
|
+ confirmRemoveAllDialog: false,
|
|
|
+ alertMessageText: '',
|
|
|
+ sendingAlertConfirmation: false,
|
|
|
+ sendingAlertMessage: false,
|
|
|
newTranscriptSheetHistoryLoading: false,
|
|
|
+ subscriptionsLoading: false,
|
|
|
newSessionLoading: false,
|
|
|
newSessionName: '-',
|
|
|
newSessionSessionCount: null,
|
|
|
@@ -417,15 +554,152 @@ export default {
|
|
|
currentPage: 'current',
|
|
|
perPage: 'per_page',
|
|
|
pageKey: 'page'
|
|
|
+ },
|
|
|
+
|
|
|
+ subscriptionsApi: APIGateway.subscription.APIAdresses.base,
|
|
|
+ subscriptionsTable: {
|
|
|
+ columns: [
|
|
|
+ {
|
|
|
+ name: 'id',
|
|
|
+ required: true,
|
|
|
+ label: 'شناسه',
|
|
|
+ align: 'left',
|
|
|
+ field: row => row.id
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'mobile_number',
|
|
|
+ required: true,
|
|
|
+ label: 'تلفن همراه',
|
|
|
+ align: 'left',
|
|
|
+ field: row => row.owner_info.mobile_number
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'email',
|
|
|
+ required: true,
|
|
|
+ label: 'ایمیل',
|
|
|
+ align: 'left',
|
|
|
+ field: row => row.owner_info.email
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'is_enabled',
|
|
|
+ required: true,
|
|
|
+ label: 'وضعیت',
|
|
|
+ align: 'left',
|
|
|
+ field: row => row.is_enabled ? 'فعال' : 'غیرفعال'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'creation_time',
|
|
|
+ required: true,
|
|
|
+ label: 'تاریخ ایجاد',
|
|
|
+ align: 'left',
|
|
|
+ field: row => ShamsiDate.getDateTime(row.creation_time)
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'last_modification_time',
|
|
|
+ required: true,
|
|
|
+ label: 'تاریخ آخرین تغییر',
|
|
|
+ align: 'left',
|
|
|
+ field: row => ShamsiDate.getDateTime(row.last_modification_time)
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'actions',
|
|
|
+ required: true,
|
|
|
+ label: 'عملیات',
|
|
|
+ align: 'left',
|
|
|
+ field: ''
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ data: []
|
|
|
+ },
|
|
|
+ subscriptionsFilterInputs: [
|
|
|
+ { type: 'hidden', name: 'source_type', value: 'UNIT' },
|
|
|
+ { type: 'hidden', name: 'source_id', value: this.$route.params.id }
|
|
|
+ ],
|
|
|
+ subscriptionsTableKeys: {
|
|
|
+ data: 'results',
|
|
|
+ total: 'count',
|
|
|
+ currentPage: 'current',
|
|
|
+ perPage: 'per_page',
|
|
|
+ pageKey: 'page'
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
+ computed: {
|
|
|
+ confirmRemoveAllMessage () {
|
|
|
+ return 'آیا از حذف همه دنبال کنندگان اطمینان دارید؟'
|
|
|
+ }
|
|
|
+ },
|
|
|
mounted () {
|
|
|
// this.getCategories()
|
|
|
this.setActionBtn()
|
|
|
this.mounted = true
|
|
|
},
|
|
|
methods: {
|
|
|
+ deleteAllSubscriptions () {
|
|
|
+ this.deleteAllLoading = true
|
|
|
+ APIGateway.subscription.deleteAllSubscriptions({
|
|
|
+ source_type: 'UNIT',
|
|
|
+ source_id: this.$route.params.id
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.$refs.subscriptionsEntityIndex.search()
|
|
|
+ this.$q.notify({
|
|
|
+ type: 'positive',
|
|
|
+ message: 'دنبال کنندگان حذف شدند',
|
|
|
+ position: 'center'
|
|
|
+ })
|
|
|
+ this.deleteAllLoading = false
|
|
|
+ this.confirmRemoveAllDialog = false
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ this.deleteAllLoading = false
|
|
|
+ this.confirmRemoveAllDialog = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getSubscriptionsListExcel () {
|
|
|
+ this.exportReportLoading = true
|
|
|
+ const status = null
|
|
|
+ APIGateway.subscription.exportSubscriptionsListReport({
|
|
|
+ source_type: 'UNIT',
|
|
|
+ source_id: this.$route.params.id,
|
|
|
+ report_type: 'subscriptions_list',
|
|
|
+ status
|
|
|
+ })
|
|
|
+ .then((xlsxData) => {
|
|
|
+ Assist.saveXlsx(xlsxData, this.$route.params.id)
|
|
|
+ this.exportReportLoading = false
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ this.exportReportLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ sendAlertMessage() {
|
|
|
+ if (!this.alertMessageText.trim()) {
|
|
|
+ this.$q.notify({
|
|
|
+ type: 'negative',
|
|
|
+ message: 'متن پاسخ را کامل کنید.',
|
|
|
+ position: 'top'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.sendingAlertMessage = true
|
|
|
+ APIGateway.subscription.sendMessage({
|
|
|
+ source_type: 'UNIT',
|
|
|
+ source_id: this.$route.params.id,
|
|
|
+ message: this.alertMessageText
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.alertMessageText = ''
|
|
|
+ this.showAlertDialog = false
|
|
|
+ this.sendingAlertConfirmation = false
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.error('خطا در ارسال:', err)
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.sendingAlertMessage = false
|
|
|
+ })
|
|
|
+ },
|
|
|
getCategories () {
|
|
|
this.categories.loading = true
|
|
|
APIGateway.unitCategory.index()
|
|
|
@@ -452,7 +726,10 @@ export default {
|
|
|
this.$refs.categoryEntityEdit.editEntity()
|
|
|
},
|
|
|
getRemoveMessage (row) {
|
|
|
- return 'آیا از حذف ' + row.title + ' اطمینان دارید؟'
|
|
|
+ if (row.title) {
|
|
|
+ return 'آیا از حذف ' + row.title + ' اطمینان دارید؟'
|
|
|
+ }
|
|
|
+ return 'آیا از حذف اطمینان دارید؟'
|
|
|
},
|
|
|
reloadSessions () {
|
|
|
this.$refs.sessionEntityIndex.reload()
|
|
|
@@ -494,4 +771,9 @@ export default {
|
|
|
.btn-go-to-question-bank {
|
|
|
margin-right: 20px;
|
|
|
}
|
|
|
+.my-dialog-card {
|
|
|
+ width: 90vw; /* همیشه ۹۰٪ عرض صفحه */
|
|
|
+ max-width: 400px; /* ولی بیشتر از ۴۰۰px نشه */
|
|
|
+ min-width: 300px; /* و حداقل ۳۰۰px باشه که خیلی کوچیک نشه */
|
|
|
+}
|
|
|
</style>
|