show.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. <template>
  2. <div class="flex justify-end">
  3. <q-btn flat
  4. color="grey"
  5. @click="$router.go(-1)">
  6. بازگشت
  7. >
  8. </q-btn>
  9. </div>
  10. <q-card class="AdminClassroomShow">
  11. <q-tabs v-model="tab"
  12. dense
  13. class="text-grey"
  14. active-color="primary"
  15. indicator-color="primary"
  16. align="justify"
  17. narrow-indicator>
  18. <q-tab name="classroomInfo"
  19. label="مشخصات" />
  20. <q-tab name="educations"
  21. label="لیست جلسات" />
  22. <q-tab name="projects"
  23. label="پروژه‌ها" />
  24. <q-tab name="movies2"
  25. label="آزمون" />
  26. <q-tab name="members"
  27. label="اندیشه جویان" />
  28. <q-tab name="activity_sheet"
  29. label="فعالیت کلاسی" />
  30. <q-tab name="live_streaming_url"
  31. label="بخش آنلاین" />
  32. </q-tabs>
  33. <q-separator />
  34. <q-tab-panels v-model="tab"
  35. animated>
  36. <q-tab-panel name="classroomInfo"
  37. class="q-pa-none">
  38. <entity-edit v-if="mounted"
  39. ref="classroomEntityEdit"
  40. :key="classroomEntityEditKey"
  41. v-model:value="inputs"
  42. title="مشخصات دوره آموزشی"
  43. :api="api"
  44. :entity-id-key="entityIdKey"
  45. :entity-param-key="entityParamKey"
  46. :show-route-name="showRouteName"
  47. :show-close-button="false"
  48. :show-edit-button="false"
  49. :show-expand-button="false"
  50. :show-save-button="false"
  51. :show-reload-button="false"
  52. :after-load-input-data="afterLoadInputData">
  53. <template #after-form-builder>
  54. <div class="flex justify-end q-mt-md">
  55. <q-btn color="primary"
  56. label="بروزرسانی اطلاعات"
  57. @click="updateClassroom" />
  58. </div>
  59. </template>
  60. </entity-edit>
  61. <q-skeleton v-else
  62. type="rect"
  63. height="200px" />
  64. </q-tab-panel>
  65. <q-tab-panel name="educations"
  66. class="q-pa-none">
  67. <entity-index v-if="mounted"
  68. ref="sessionList"
  69. v-model:value="sessionListInputs"
  70. title="لیست جلسات"
  71. :api="sessionListApi"
  72. :table="sessionListTable"
  73. :table-keys="sessionListTableKeys"
  74. :show-search-button="false"
  75. :show-reload-button="false"
  76. :show-expand-button="false">
  77. <template #toolbar>
  78. <q-btn color="primary"
  79. outline
  80. :loading="addNewSessionLoading"
  81. @click="addNewSession">
  82. افزودن جلسه
  83. </q-btn>
  84. </template>
  85. <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
  86. <template v-if="inputData.col.name === 'number'">
  87. {{ inputData.rowNumber }}
  88. </template>
  89. <template v-else-if="inputData.col.name === 'actions'">
  90. <div class="action-column-entity-index">
  91. <q-btn size="md"
  92. color="primary"
  93. label="جزییات"
  94. :to="{name: 'Admin.Session.Show', params: {id: inputData.props.row.id}}"
  95. class="q-mr-md" />
  96. <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
  97. </div>
  98. </template>
  99. <template v-else>
  100. {{ inputData.col.value }}
  101. </template>
  102. </template>
  103. </entity-index>
  104. <q-skeleton v-else
  105. type="rect"
  106. height="200px" />
  107. </q-tab-panel>
  108. <q-tab-panel name="projects"
  109. class="q-pa-none">
  110. <entity-index v-if="mounted"
  111. ref="projectList"
  112. v-model:value="projectListInputs"
  113. title="لیست پروژه ها"
  114. :api="projectListApi"
  115. :table="projectListTable"
  116. :table-keys="projectListTableKeys"
  117. :show-search-button="false"
  118. :show-reload-button="false"
  119. :show-expand-button="false">
  120. <template #toolbar>
  121. <q-btn color="primary"
  122. outline
  123. :loading="addNewProjectLoading"
  124. @click="addNewProject">
  125. افزودن پروژه جدید
  126. </q-btn>
  127. </template>
  128. <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
  129. <template v-if="inputData.col.name === 'number'">
  130. {{ inputData.rowNumber }}
  131. </template>
  132. <template v-else-if="inputData.col.name === 'actions'">
  133. <div class="action-column-entity-index">
  134. <q-btn size="md"
  135. color="primary"
  136. label="جزییات"
  137. :to="{name: 'Admin.Classroom.Project.Show', params: {id: $route.params.id, project_id: inputData.props.row.id}}"
  138. class="q-mr-md" />
  139. <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
  140. </div>
  141. </template>
  142. <template v-else-if="inputData.col.name === 'members'">
  143. <div class="action-column-entity-index">
  144. <q-btn size="md"
  145. color="primary"
  146. outline
  147. label="بررسی پروژه"
  148. :to="{name: 'Admin.Classroom.Project.Members', params: {id: $route.params.id, project_id: inputData.props.row.id}}"
  149. class="q-mr-md" />
  150. </div>
  151. </template>
  152. <template v-else>
  153. {{ inputData.col.value }}
  154. </template>
  155. </template>
  156. </entity-index>
  157. <q-skeleton v-else
  158. type="rect"
  159. height="200px" />
  160. </q-tab-panel>
  161. <q-tab-panel name="movies2">
  162. آزمون
  163. </q-tab-panel>
  164. <q-tab-panel name="members"
  165. class="q-pa-none">
  166. <entity-index v-if="mounted"
  167. ref="membersList"
  168. v-model:value="membersListInputs"
  169. title="لیست کاربران"
  170. :api="membersListApi"
  171. :table="membersListTable"
  172. :table-keys="membersListTableKeys"
  173. :show-search-button="false"
  174. :show-reload-button="false"
  175. :show-expand-button="false">
  176. <template #toolbar>
  177. <q-btn color="primary"
  178. :loading="exportReportLoading"
  179. @click="getMembersExcel">
  180. خروجی اکسل
  181. </q-btn>
  182. </template>
  183. <template v-slot:entity-index-table-cell="{inputData}">
  184. <template v-if="inputData.col.name === 'number'">
  185. {{ inputData.rowNumber }}
  186. </template>
  187. <template v-else-if="inputData.col.name === 'action'">
  188. <div class="action-column-entity-index">
  189. <q-btn v-if="inputData.props.row.status !== 'DROPPED_BY_ADMIN' && inputData.props.row.status !== 'DROPPED_BY_ITSELF'"
  190. size="md"
  191. color="red"
  192. outline
  193. label="انصراف"
  194. :loading="dropClassroomByAdminLoading"
  195. class="q-mr-md"
  196. @click="dropClassroomByAdmin(inputData.props.row)" />
  197. <q-btn v-if="inputData.props.row.status === 'ENROLLED'"
  198. size="md"
  199. color="primary"
  200. outline
  201. label="ایجاد صورتحساب"
  202. :loading="createInvoiceLoading"
  203. class="q-mr-md"
  204. @click="createInvoiceForClassroom(inputData.props.row)" />
  205. </div>
  206. </template>
  207. <template v-else>
  208. {{ inputData.col.value }}
  209. </template>
  210. </template>
  211. </entity-index>
  212. <q-skeleton v-else
  213. type="rect"
  214. height="200px" />
  215. </q-tab-panel>
  216. <q-tab-panel name="activity_sheet"
  217. class="q-pa-none">
  218. <entity-index v-if="mounted"
  219. ref="activitySheetList"
  220. v-model:value="activitySheetListInputs"
  221. title="فعالیت کلاسی"
  222. :api="activitySheetListApi"
  223. :table="activitySheetListTable"
  224. :table-keys="activitySheetListTableKeys"
  225. :show-search-button="false"
  226. :show-reload-button="false"
  227. :show-expand-button="false">
  228. <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
  229. <template v-if="inputData.col.name === 'actions'">
  230. <div class="action-column-entity-index">
  231. <q-btn size="md"
  232. color="primary"
  233. outline
  234. label="سابقه آموزشی"
  235. class="q-mr-md" />
  236. <!-- :to="{name: 'Admin.Session.Show', params: {id: inputData.props.row.id}}"-->
  237. <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
  238. </div>
  239. </template>
  240. <template v-else>
  241. {{ inputData.col.value }}
  242. </template>
  243. </template>
  244. </entity-index>
  245. <q-skeleton v-else
  246. type="rect"
  247. height="200px" />
  248. </q-tab-panel>
  249. <q-tab-panel name="live_streaming_url">
  250. <q-btn class="full-width q-mb-lg"
  251. color="primary"
  252. @click="goToLiveStreamUrl">
  253. رفتن به کلاس
  254. </q-btn>
  255. <iframe :src="classroom.live_streaming_url"
  256. title="W3Schools Free Online Web Tutorials"
  257. style="height: 80vh"
  258. class="full-width" />
  259. </q-tab-panel>
  260. </q-tab-panels>
  261. </q-card>
  262. </template>
  263. <script>
  264. import { shallowRef } from 'vue'
  265. import Assist from 'src/assets/js/Assist.js'
  266. import Enums from 'src/assets/Enums/Enums.js'
  267. import ShamsiDate from 'src/assets/ShamsiDate.js'
  268. import { APIGateway } from 'src/api/APIGateway.js'
  269. import { Classroom } from 'src/models/Classroom.js'
  270. import { EntityEdit, EntityIndex } from 'quasar-crud'
  271. import { FormBuilderAssist } from 'quasar-form-builder'
  272. import BtnControl from 'src/components/Control/btn.vue'
  273. import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
  274. import { Project } from 'src/models/Project'
  275. const BtnControlComp = shallowRef(BtnControl)
  276. export default {
  277. name: 'Admin.Classroom.Show',
  278. components: {
  279. EntityEdit,
  280. EntityIndex,
  281. DeleteBtn
  282. },
  283. data () {
  284. const classroomId = this.$route.params.id
  285. return {
  286. mounted: false,
  287. addNewSessionLoading: false,
  288. addNewProjectLoading: false,
  289. createInvoiceLoading: false,
  290. classroomEntityEditKey: Date.now(),
  291. tab: 'classroomInfo',
  292. api: null,
  293. entityIdKey: 'id',
  294. entityParamKey: 'id',
  295. showRouteName: 'Admin.Classroom.Show',
  296. inputs: [
  297. { type: 'separator', name: 'space', label: 'مشخصات دوره', className: 'custom-separator', col: 'col-12' },
  298. { type: 'file', name: 'thumbnail', responseKey: 'thumbnail', label: 'آپلود عکس دوره', col: 'col-md-3 col-12' },
  299. { type: 'separator', name: 'space', size: '0', col: 'col-md-12' },
  300. { type: 'select', name: 'category', responseKey: 'unit_info.category_info.id', options: [], value: null, placeholder: ' ', label: 'دسته بندی', col: 'col-md-3 col-12' },
  301. { type: 'select', name: 'unit', responseKey: 'unit', options: [], value: null, placeholder: ' ', label: 'درس', col: 'col-md-3 col-12' },
  302. { type: 'select', name: 'holding_type', responseKey: 'holding_type', options: Enums.classroomHoldingTypes, value: null, placeholder: ' ', label: 'نوع برگزاری', col: 'col-md-3 col-12' },
  303. { type: 'input', name: 'price', responseKey: 'price', placeholder: ' ', label: 'هزینه برگزاری', col: 'col-md-3 col-12' },
  304. { type: 'input', name: 'live_streaming_url', responseKey: 'live_streaming_url', placeholder: ' ', label: 'لینک مکان مجازی دوره', col: 'col-12' },
  305. { type: 'inputEditor', name: 'classroom_address', responseKey: 'classroom_address', placeholder: ' ', label: 'آدرس مکان فیزیکی دوره', col: 'col-12' },
  306. {
  307. type: 'select',
  308. name: 'holding_year',
  309. responseKey: 'holding_year',
  310. options: [1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410],
  311. value: null,
  312. label: 'انتخاب سال دوره',
  313. placeholder: ' ',
  314. col: 'col-md-3'
  315. },
  316. {
  317. type: 'select',
  318. name: 'holding_month',
  319. responseKey: 'holding_month',
  320. options: [
  321. 'فروردین',
  322. 'اردیبهشت',
  323. 'خرداد',
  324. 'تیر',
  325. 'مرداد',
  326. 'شهریور',
  327. 'مهر',
  328. 'آبان',
  329. 'آذر',
  330. 'دی',
  331. 'بهمن',
  332. 'اسفند'
  333. ],
  334. value: null,
  335. label: 'انتخاب ماه دوره',
  336. placeholder: ' ',
  337. col: 'col-md-3'
  338. },
  339. { type: 'input', name: 'sessions_frequency', responseKey: 'sessions_frequency', placeholder: ' ', label: 'دوره تناوب', col: 'col-12' },
  340. { type: 'select', name: 'professor', responseKey: 'professor', options: [], value: null, placeholder: ' ', label: 'استاد دوره', col: 'col-md-3 col-12' },
  341. { type: 'separator', name: 'space', label: 'مشخصات اندیشه جو', className: 'custom-separator', col: 'col-12' },
  342. { type: 'select', name: 'audience_status_wwwww', responseKey: 'audience_status_wwwww', options: [], placeholder: ' ', label: 'وضعیت(؟)', col: 'col-md-3 col-12' },
  343. { type: 'select', name: 'category', responseKey: 'category', options: [], placeholder: ' ', label: 'مجموعه(؟)', col: 'col-md-3 col-12' },
  344. { type: 'select', name: 'audience_gender_type', responseKey: 'audience_gender_type', options: Enums.classroomGenders, placeholder: ' ', label: 'جنسیت', col: 'col-md-3 col-12' },
  345. { type: 'select', name: 'audience_bashgah_wwwww', responseKey: 'audience_bashgah_wwwww', options: [], placeholder: ' ', label: 'باشگاه(؟)', col: 'col-md-3 col-12' },
  346. { type: 'separator', name: 'space', label: 'تنظیمات دوره', className: 'custom-separator', col: 'col-12' },
  347. { type: 'input', name: 'capacity', responseKey: 'capacity', placeholder: ' ', label: 'ظرفیت گروه درسی', col: 'col-md-3 col-12' },
  348. { type: 'input', name: 'allowed_absence_count', responseKey: 'allowed_absence_count', placeholder: ' ', label: 'تعداد مجاز غیبت', col: 'col-md-3 col-12' },
  349. { type: 'input', name: 'effective_absence_coefficient', responseKey: 'effective_absence_coefficient', placeholder: ' ', label: 'ضریب نمره حضور و غیاب', col: 'col-md-3 col-12' },
  350. { type: 'input', name: 'mandatory_assignment_count', responseKey: 'mandatory_assignment_count', placeholder: ' ', label: 'تعداد تکالیف اجباری', col: 'col-md-3 col-12' },
  351. { type: 'input', name: 'special_passing_mark', responseKey: 'special_passing_mark', placeholder: ' ', label: 'نمره قبولی مشروطی ها', col: 'col-md-3 col-12' },
  352. { type: 'input', name: 'minimum_conditional_passing_mark', responseKey: 'minimum_conditional_passing_mark', placeholder: ' ', label: 'نمره قبولی مشروط', col: 'col-md-3 col-12' },
  353. { type: 'input', name: 'minimum_clean_passing_mark', responseKey: 'minimum_clean_passing_mark', placeholder: ' ', label: 'نمره قبولی', col: 'col-md-3 col-12' },
  354. { type: 'separator', name: 'space', label: 'ثبت نام و حذف و اضافه', className: 'custom-separator', col: 'col-12' },
  355. { type: 'dateTime', name: 'beginning_enrollment_period', responseKey: 'beginning_enrollment_period', placeholder: ' ', label: 'تاریخ شروع پیش ثبت نام', col: 'col-md-6 col-12' },
  356. { type: 'dateTime', name: 'ending_enrollment_period', responseKey: 'ending_enrollment_period', placeholder: ' ', label: 'تاریخ پایان پیش ثبت نام', col: 'col-md-6 col-12' },
  357. { type: 'dateTime', name: 'beginning_registration_period', responseKey: 'beginning_registration_period', placeholder: ' ', label: 'تاریخ شروع ثبت نام', col: 'col-md-6 col-12' },
  358. { type: 'dateTime', name: 'ending_registration_period', responseKey: 'ending_registration_period', placeholder: ' ', label: 'تاریخ پایان ثبت نام', col: 'col-md-6 col-12' },
  359. { type: 'input', name: 'registration_period_refund_percent', responseKey: 'registration_period_refund_percent', placeholder: ' ', label: 'درصد برگشت هزینه انصراف در بازه ثبت نام', col: 'col-md-3 col-12' },
  360. { type: 'checkbox', name: 'allow_dropping_on_enrollment_period', responseKey: 'allow_dropping_on_enrollment_period', label: 'امکان حذف در بازه پیش ثبت نام', col: 'col-md-3 col-12' },
  361. { type: 'checkbox', name: 'allow_adding_on_registration_period', responseKey: 'allow_adding_on_registration_period', label: 'امکان اضافه کردن در بازه ثبت نام', col: 'col-md-3 col-12' },
  362. { type: 'checkbox', name: 'allow_dropping_on_registration_period', responseKey: 'allow_dropping_on_registration_period', label: 'امکان حذف ثبت نام در بازه ثبت نام', col: 'col-md-3 col-12' },
  363. { type: 'dateTime', name: 'beginning_drop_add_period', responseKey: 'beginning_drop_add_period', placeholder: ' ', label: 'تاریخ شروع حذف و اضافه', col: 'col-md-6 col-12' },
  364. { type: 'dateTime', name: 'ending_drop_add_period', responseKey: 'ending_drop_add_period', placeholder: ' ', label: 'تاریخ پایان حذف و اضافه', col: 'col-md-6 col-12' },
  365. { type: 'input', name: 'drop_add_period_refund_percent', responseKey: 'drop_add_period_refund_percent', placeholder: ' ', label: 'درصد برگشت هزینه انصراف در بازه حذف و اضافه', col: 'col-md-3 col-12' },
  366. { type: 'checkbox', name: 'allow_adding_on_drop_add_period', responseKey: 'allow_adding_on_drop_add_period', label: 'امکان اضافه شدن در بازه حذف و اضافه', col: 'col-md-3 col-12' },
  367. { type: 'checkbox', name: 'allow_dropping_on_drop_add_period', responseKey: 'allow_dropping_on_drop_add_period', label: 'امکان حذف در بازه حذف و اضافه', col: 'col-md-3 col-12' },
  368. { type: 'dateTime', name: 'publish_time', responseKey: 'publish_time', placeholder: ' ', label: 'تاریخ انتشار', col: 'col-md-6 col-12' },
  369. { type: 'separator', name: 'space', label: 'قوانین', className: 'custom-separator', col: 'col-12' },
  370. { type: 'inputEditor', name: 'rules', responseKey: 'rules', label: 'قوانین دوره آموزشی', col: 'col-12' },
  371. { type: 'inputEditor', name: 'description', responseKey: 'description', label: 'توضیحات', col: 'col-12' },
  372. { type: 'inputEditor', name: 'specification', responseKey: 'specification', label: 'مشخصات', col: 'col-12' },
  373. { type: 'inputEditor', name: 'bulletin', responseKey: 'bulletin', label: 'تابلو اعلانات', col: 'col-12' },
  374. // -----------------------------------------------------------------------------------------------------------
  375. { type: 'separator', name: 'space', label: 'موارد زیر در طرح نبودند', className: 'custom-separator', col: 'col-12' },
  376. { type: 'select', name: 'audience_role', responseKey: 'audience_role', options: Enums.groups, placeholder: ' ', label: 'نقش', col: 'col-md-4 col-12' },
  377. { type: 'hidden', name: 'id', responseKey: 'id', label: 'id', col: 'col-md-3 col-12' }
  378. ],
  379. classroom: new Classroom(),
  380. sessionListInputs: [
  381. { type: 'hidden', name: 'classroom', value: this.$route.params.id, label: 'نام دوره', col: 'col-12' }
  382. ],
  383. sessionListApi: APIGateway.session.APIAdresses.base,
  384. sessionListTable: {
  385. columns: [
  386. {
  387. name: 'number',
  388. required: true,
  389. label: 'شماره',
  390. align: 'left',
  391. field: () => ''
  392. },
  393. {
  394. name: 'id',
  395. required: true,
  396. label: 'شناسه',
  397. align: 'left',
  398. field: row => row.id
  399. },
  400. {
  401. name: 'title',
  402. required: true,
  403. label: 'عنوان جلسه',
  404. align: 'left',
  405. field: row => row.title
  406. },
  407. {
  408. name: 'creation_time',
  409. required: true,
  410. label: 'زمان شروع جلسه',
  411. align: 'left',
  412. field: row => row.beginning_time ? ShamsiDate.getDateTime(row.beginning_time) : '-'
  413. },
  414. {
  415. name: 'last_modification_time',
  416. required: true,
  417. label: 'زمان پایان جلسه',
  418. align: 'left',
  419. field: row => row.ending_time ? ShamsiDate.getDateTime(row.ending_time) : '-'
  420. },
  421. {
  422. name: 'actions',
  423. required: true,
  424. label: 'عملیات',
  425. align: 'left',
  426. field: ''
  427. }
  428. ]
  429. },
  430. sessionListTableKeys: {
  431. data: 'results',
  432. total: 'count',
  433. currentPage: 'current',
  434. perPage: 'per_page',
  435. pageKey: 'page'
  436. },
  437. projectListInputs: [
  438. { type: 'hidden', name: 'classroom', value: this.$route.params.id }
  439. ],
  440. projectListApi: APIGateway.project.APIAdresses.base,
  441. projectListTable: {
  442. columns: [
  443. {
  444. name: 'number',
  445. required: true,
  446. label: 'شماره',
  447. align: 'left',
  448. field: () => ''
  449. },
  450. {
  451. name: 'id',
  452. required: true,
  453. label: 'شناسه',
  454. align: 'left',
  455. field: row => row.id
  456. },
  457. {
  458. name: 'title',
  459. required: true,
  460. label: 'عنوان پروژه',
  461. align: 'left',
  462. field: row => row.title
  463. },
  464. {
  465. name: 'type',
  466. required: true,
  467. label: 'نوع',
  468. align: 'left',
  469. field: row => (new Project(row)).typeEnums
  470. },
  471. {
  472. name: 'creation_time',
  473. required: true,
  474. label: 'زمان شروع پروژه',
  475. align: 'left',
  476. field: row => row.beginning_doing_period ? ShamsiDate.getDateTime(row.beginning_doing_period) : '-'
  477. },
  478. {
  479. name: 'creation_time',
  480. required: true,
  481. label: 'مهلت ارسال پروژه',
  482. align: 'left',
  483. field: row => row.ending_doing_period ? ShamsiDate.getDateTime(row.ending_doing_period) : '-'
  484. },
  485. {
  486. name: 'members',
  487. required: true,
  488. label: 'بررسی',
  489. align: 'left',
  490. field: ''
  491. },
  492. {
  493. name: 'actions',
  494. required: true,
  495. label: 'عملیات',
  496. align: 'left',
  497. field: ''
  498. }
  499. ]
  500. },
  501. projectListTableKeys: {
  502. data: 'results',
  503. total: 'count',
  504. currentPage: 'current',
  505. perPage: 'per_page',
  506. pageKey: 'page'
  507. },
  508. dropClassroomByAdminLoading: false,
  509. exportReportLoading: false,
  510. membersListInputs: [
  511. { type: 'hidden', name: 'classroom', value: classroomId },
  512. { type: 'select', name: 'status', options: [{ label: 'ثبت نام شده', value: 'REGISTERED' }, { label: 'پیش ثبت نام شده', value: 'ENROLLED' }, { label: 'حذف توسط اندیشه جو', value: 'DROPPED_BY_ITSELF' }, { label: 'حذف توسط ادمین', value: 'DROPPED_BY_ADMIN' }], label: 'وضعیت', placeholder: ' ', col: 'col-md-3 col-12' },
  513. { type: 'select', name: 'invoice__status', options: [{ label: 'پرداخت کامل', value: 'PAID_FULL' }, { label: 'پرداخت قسطی', value: 'PAYING_IN_INSTALMENT' }], label: 'نوع صورتحساب', placeholder: ' ', col: 'col-md-3 col-12' },
  514. { type: BtnControlComp, name: 'btn', label: 'جستجو', placeholder: ' ', atClick: () => {}, col: 'col-md-2 col-12' }
  515. ],
  516. membersListApi: APIGateway.classroom.APIAdresses.members,
  517. membersListTable: {
  518. columns: [
  519. {
  520. name: 'number',
  521. required: true,
  522. label: 'شماره',
  523. align: 'left',
  524. field: () => ''
  525. },
  526. {
  527. name: 'id',
  528. required: true,
  529. label: 'شناسه',
  530. align: 'left',
  531. field: row => row.id
  532. },
  533. {
  534. name: 'owner_info.fullname',
  535. required: true,
  536. label: 'نام و نام خانوادگی',
  537. align: 'left',
  538. field: row => row.owner_info.firstname + ' ' + row.owner_info.lastname
  539. },
  540. {
  541. name: 'owner_info.national_code',
  542. required: true,
  543. label: 'کد ملی',
  544. align: 'left',
  545. field: row => row.owner_info.national_code
  546. },
  547. {
  548. name: 'owner_info.mobile_number',
  549. required: true,
  550. label: 'تلفن همراه',
  551. align: 'left',
  552. field: row => row.owner_info.mobile_number
  553. },
  554. {
  555. name: 'owner_info.email',
  556. required: true,
  557. label: 'ایمیل',
  558. align: 'left',
  559. field: row => row.owner_info.email
  560. },
  561. {
  562. name: 'owner_info.email',
  563. required: true,
  564. label: 'وضعیت',
  565. align: 'left',
  566. field: row => (new Classroom()).getUserRegisterInfoLabel(row.status)
  567. },
  568. {
  569. name: 'action',
  570. required: true,
  571. label: ' ',
  572. align: 'left',
  573. field: ''
  574. }
  575. ],
  576. data: []
  577. },
  578. membersListTableKeys: {
  579. data: 'results',
  580. total: 'count',
  581. currentPage: 'current',
  582. perPage: 'per_page',
  583. pageKey: 'page'
  584. },
  585. activitySheetListInputs: [
  586. { type: 'hidden', name: 'classroom', value: classroomId },
  587. { type: 'select', name: 'status', value: null, label: 'وضعیت', placeholder: ' ', col: 'col-md-3 col-12' },
  588. { type: BtnControlComp, name: 'btn', label: 'جستجو', placeholder: ' ', atClick: () => {}, col: 'col-md-2 col-12' }
  589. ],
  590. activitySheetListApi: APIGateway.classroom.APIAdresses.activitySheet,
  591. activitySheetListTable: {
  592. columns: [
  593. {
  594. name: 'id',
  595. required: true,
  596. label: 'شماره',
  597. align: 'left',
  598. field: row => row.id
  599. },
  600. {
  601. name: 'owner_info.fullname',
  602. required: true,
  603. label: 'نام و نام خانوادگی',
  604. align: 'left',
  605. field: row => row.owner_info.firstname + ' ' + row.owner_info.lastname
  606. },
  607. {
  608. name: 'owner_info.fullname',
  609. required: true,
  610. label: 'کد ملی',
  611. align: 'left',
  612. field: row => row.owner_info.national_code
  613. },
  614. {
  615. name: 'is_project_done',
  616. required: true,
  617. label: 'پروژه',
  618. align: 'left',
  619. field: row => row.is_project_done
  620. },
  621. {
  622. name: 'done_assignment_count',
  623. required: true,
  624. label: 'تکالیف انجام شده',
  625. align: 'left',
  626. field: row => row.done_assignment_count
  627. },
  628. {
  629. name: 'is_allowed_absence_count',
  630. required: true,
  631. label: 'حضور و غیاب',
  632. align: 'left',
  633. field: row => row.is_allowed_absence_count // bool
  634. },
  635. {
  636. name: 'attendance_score',
  637. required: true,
  638. label: 'نمره حضور و غیاب',
  639. align: 'left',
  640. field: row => row.attendance_score
  641. },
  642. {
  643. name: 'final_test',
  644. required: true,
  645. label: 'آزمون',
  646. align: 'left',
  647. field: row => row.final_test // number - null
  648. },
  649. {
  650. name: 'final_status',
  651. required: true,
  652. label: 'وضعیت نهایی',
  653. align: 'left',
  654. field: row => row.final_status
  655. },
  656. {
  657. name: 'actions',
  658. required: true,
  659. label: 'سابقه آموزشی',
  660. align: 'left',
  661. field: ''
  662. }
  663. ],
  664. data: []
  665. },
  666. activitySheetListTableKeys: {
  667. data: 'results',
  668. total: 'count',
  669. currentPage: 'current',
  670. perPage: 'per_page',
  671. pageKey: 'page'
  672. }
  673. }
  674. },
  675. computed: {
  676. selectedCategoryId () {
  677. return this.getInputValue('category')
  678. }
  679. },
  680. watch: {
  681. selectedCategoryId () {
  682. if (!this.mounted) {
  683. return
  684. }
  685. this.setInputValue('unit', null)
  686. this.getUnits(this.selectedCategoryId)
  687. }
  688. },
  689. mounted () {
  690. this.api = APIGateway.classroom.APIAdresses.byId(this.$route.params.id)
  691. this.setMembersListActionBtn()
  692. this.setActivitySheetListActionBtn()
  693. this.preLoadData()
  694. .then(() => {
  695. this.mounted = true
  696. })
  697. .catch(() => {
  698. this.mounted = true
  699. })
  700. },
  701. methods: {
  702. addNewSession () {
  703. this.addNewSessionLoading = true
  704. APIGateway.session.create({
  705. title: '-',
  706. classroom: this.$route.params.id
  707. })
  708. .then(() => {
  709. this.$refs.sessionList.search()
  710. this.addNewSessionLoading = false
  711. })
  712. .catch(() => {
  713. this.addNewSessionLoading = false
  714. })
  715. },
  716. addNewProject () {
  717. this.addNewProjectLoading = true
  718. APIGateway.project.create({
  719. title: '-',
  720. classroom: this.$route.params.id
  721. })
  722. .then(() => {
  723. this.$refs.projectList.search()
  724. this.addNewProjectLoading = false
  725. })
  726. .catch(() => {
  727. this.addNewProjectLoading = false
  728. })
  729. },
  730. setMembersListActionBtn () {
  731. FormBuilderAssist.setAttributeByName(this.membersListInputs, 'btn', 'atClick', this.searchMembersList)
  732. },
  733. setActivitySheetListActionBtn () {
  734. FormBuilderAssist.setAttributeByName(this.activitySheetListInputs, 'btn', 'atClick', this.searchActivitySheetList)
  735. },
  736. searchMembersList () {
  737. this.$refs.membersList.search()
  738. },
  739. searchActivitySheetList () {
  740. this.$refs.activitySheet.search()
  741. },
  742. goToLiveStreamUrl () {
  743. window.open(this.classroom.live_streaming_url, '_blank')
  744. },
  745. afterLoadInputData (data) {
  746. this.classroom = new Classroom(data)
  747. // const gg = data.beginning_enrollment_period.replace('T', ' ')
  748. // this.setInputAttr('beginning_enrollment_period', 'value', gg)
  749. },
  750. setInputAttr (name, attr, value) {
  751. FormBuilderAssist.setAttributeByName(this.inputs, name, attr, value)
  752. // this.$refs.classroomEntityEdit.setInputAttributeByName(name, attr, value)
  753. },
  754. preLoadData () {
  755. return new Promise((resolve, reject) => {
  756. APIGateway.classroom.get(this.$route.params.id)
  757. .then((classroom) => {
  758. this.setInputAttr('category', 'value', classroom.unit_info.category_info.id)
  759. this.setInputAttr('unit', 'value', classroom.unit)
  760. this.beforeLoadInputData(classroom)
  761. .then((classroom) => {
  762. resolve()
  763. })
  764. .catch(() => {
  765. reject()
  766. })
  767. })
  768. .catch(() => {
  769. reject()
  770. })
  771. })
  772. },
  773. beforeLoadInputData (responseData) {
  774. return new Promise((resolve, reject) => {
  775. const promise1 = this.getProfessors()
  776. const promise2 = this.getCategories()
  777. const promise3 = this.getUnits(responseData.unit_info.category)
  778. this.$nextTick(() => {
  779. Promise.all([promise1, promise2, promise3])
  780. .then(() => {
  781. // this.setInputAttr('category', 'value', responseData.unit_info.category)
  782. // this.setInputAttr('unit', 'value', responseData.unit)
  783. this.classroomEntityEditKey = Date.now()
  784. resolve()
  785. })
  786. .catch(() => {
  787. reject()
  788. })
  789. })
  790. })
  791. },
  792. getProfessors () {
  793. return APIGateway.user.index({ per_page: 9999, role: 'professor' })
  794. .then((users) => {
  795. this.setInputAttr('professor', 'options', users.list.list.map(item => {
  796. return {
  797. value: item.id,
  798. label: this.getUserFullname(item)
  799. }
  800. }))
  801. })
  802. .catch(() => {})
  803. },
  804. getCategories () {
  805. return APIGateway.unitCategory.index({ per_page: 9999 })
  806. .then((categories) => {
  807. this.setInputAttr('category', 'options', categories.list.list.map(item => {
  808. return {
  809. value: item.id,
  810. label: item.title
  811. }
  812. }))
  813. })
  814. .catch(() => {})
  815. },
  816. getUnits (selectedcategoryId) {
  817. return APIGateway.unit.index({ per_page: 9999, category: selectedcategoryId })
  818. .then((units) => {
  819. this.setInputAttr('unit', 'options', units.list.list.map(item => {
  820. return {
  821. value: item.id,
  822. label: item.title
  823. }
  824. }))
  825. })
  826. .catch(() => {})
  827. },
  828. getUserFullname (user) {
  829. return user.firstname + ' ' + user.lastname
  830. },
  831. getSelectOptions (result, value, label) {
  832. return result.map(item => {
  833. return {
  834. value: item[value],
  835. label: item[label]
  836. }
  837. })
  838. },
  839. getInputValue (name) {
  840. const inputIndex = this.inputs.findIndex(input => input.name === name)
  841. return this.inputs[inputIndex].value
  842. },
  843. setInputValue (name, value) {
  844. const inputIndex = this.inputs.findIndex(input => input.name === name)
  845. this.inputs[inputIndex].value = value
  846. },
  847. loadSelectOptions (name, value, setNewInputData) {
  848. const inputIndex = this.inputs.findIndex(input => input.name === name)
  849. this.inputs[inputIndex].options = value
  850. if (typeof setNewInputData === 'function') {
  851. setNewInputData(this.inputs)
  852. }
  853. },
  854. updateClassroom () {
  855. this.$refs.classroomEntityEdit.editEntity()
  856. },
  857. getMembersExcel () {
  858. this.exportReportLoading = true
  859. const status = FormBuilderAssist.getInputsByName(this.membersListInputs, 'status').value ? FormBuilderAssist.getInputsByName(this.membersListInputs, 'status').value : null
  860. APIGateway.registration.exportReport({
  861. classroom: this.$route.params.id,
  862. type: 'users',
  863. status
  864. })
  865. .then((xlsxData) => {
  866. Assist.saveXlsx(xlsxData, this.classroom.title)
  867. this.exportReportLoading = false
  868. })
  869. .catch((e) => {
  870. this.exportReportLoading = false
  871. })
  872. },
  873. getRemoveMessage (row) {
  874. return 'آیا از حذف ' + row.title + ' اطمینان دارید؟'
  875. },
  876. dropClassroomByAdmin (row) {
  877. const classroomId = row.classroom
  878. const userId = row.owner
  879. const message = 'آیا از انصراف (' + row.owner_info.firstname + ' ' + row.owner_info.lastname + ') اطمینان دارید؟'
  880. this.$q.dialog({
  881. title: 'توجه',
  882. message,
  883. html: true,
  884. cancel: true,
  885. persistent: true
  886. }).onOk(() => {
  887. this.dropClassroomByAdminLoading = true
  888. APIGateway.classroom.dropByAdmin(classroomId, userId)
  889. .then(() => {
  890. this.dropClassroomByAdminLoading = false
  891. this.searchMembersList()
  892. })
  893. .catch(() => {
  894. this.dropClassroomByAdminLoading = false
  895. })
  896. })
  897. },
  898. createInvoiceForClassroom (row) {
  899. const classroomId = row.classroom
  900. const userId = row.owner
  901. this.createInvoiceLoading = true
  902. APIGateway.classroom.createInvoiceByAdmin(classroomId, userId)
  903. .then((invoice) => {
  904. this.$router.push({ name: 'Admin.Invoice.Show', params: { id: invoice.id } })
  905. this.createInvoiceLoading = false
  906. })
  907. .catch(() => {
  908. this.createInvoiceLoading = false
  909. })
  910. }
  911. }
  912. }
  913. </script>
  914. <style lang="scss" scoped>
  915. .AdminClassroomShow {
  916. .action-column-entity-index {
  917. display: flex;
  918. align-items: center;
  919. justify-content: flex-start;
  920. }
  921. }
  922. </style>