create-message.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. import OPopup from '@/components/o-popup'
  2. import { sendType } from '@/constant'
  3. import request from '@/helpers/request'
  4. import { getOssUploadUrl, state } from '@/state'
  5. import dayjs from 'dayjs'
  6. import {
  7. ActionSheet,
  8. Button,
  9. Cell,
  10. CellGroup,
  11. closeToast,
  12. DatePicker,
  13. Field,
  14. Icon,
  15. Image,
  16. PickerGroup,
  17. Popup,
  18. showLoadingToast,
  19. showToast,
  20. TimePicker,
  21. Uploader
  22. } from 'vant'
  23. import { computed, defineComponent, onMounted, reactive } from 'vue'
  24. import styles from './index.module.less'
  25. import SelectSned from './select-sned'
  26. import iconStudent from '@common/images/icon_student.png'
  27. import iconTeacher from '@common/images/icon_teacher.png'
  28. import iconJiaoFu from '@common/images/icon_jiaofu.png'
  29. import ODialog from '@/components/o-dialog'
  30. import OSticky from '@/components/o-sticky'
  31. import { useRoute, useRouter } from 'vue-router'
  32. import OActionSheet from '@/components/o-action-sheet'
  33. import { formatterDatePicker } from '@/helpers/utils'
  34. import OUploadAll from '@/components/o-upload-all'
  35. import OHeader from '@/components/o-header'
  36. export default defineComponent({
  37. name: 'create-message',
  38. setup() {
  39. const router = useRouter()
  40. const route = useRoute()
  41. const forms = reactive({
  42. id: route.query.id,
  43. type: 'ADD',
  44. bucket: 'i-m',
  45. sendStatus: false,
  46. sendType: 'IMMEDIATELY' as any,
  47. textMessage: null,
  48. sendTime: null as any,
  49. sendTimeStatus: false,
  50. maxDate: dayjs(new Date()).add(60, 'day').toDate(),
  51. currentDate: [],
  52. currentTime: [dayjs().format('HH'), dayjs().format('mm')],
  53. attachments: [] as any, //群发消息附件
  54. receives: [] as any, // 群发消息对象
  55. selectStatus: false,
  56. selectList: {} as any, // 选中发送的信息
  57. delSelectItem: {} as any,
  58. delStatus: false,
  59. sureLoading: false,
  60. updateLoading: false,
  61. closeLoading: false,
  62. actions: [
  63. { name: '即时发送', value: 'IMMEDIATELY', selected: true },
  64. { name: '定时发送', value: 'SCHEDULED' }
  65. ]
  66. })
  67. const onSubmit = async () => {
  68. try {
  69. if (!forms.sendType) {
  70. showToast('请选择发送方式')
  71. return
  72. }
  73. if (!forms.textMessage) {
  74. showToast('请输入发送内容')
  75. return
  76. }
  77. if (forms.receives.length <= 0) {
  78. showToast('请选择发送对象')
  79. return
  80. }
  81. const tempAttachments: any = []
  82. forms.attachments.forEach((item: any) => {
  83. tempAttachments.push({
  84. imgUrl: item,
  85. imgMessage: item
  86. })
  87. })
  88. const tempReceives: any = []
  89. forms.receives.forEach((item: any) => {
  90. tempReceives.push({
  91. receiveType: item.receiveType,
  92. receiveId: item.receiveId
  93. })
  94. })
  95. const params: any = {
  96. sendType: forms.sendType,
  97. textMessage: forms.textMessage,
  98. attachments: tempAttachments,
  99. receives: tempReceives,
  100. sendTime: forms.sendTime
  101. }
  102. console.log(params, 'params')
  103. if (forms.id) {
  104. forms.updateLoading = true
  105. } else {
  106. forms.sureLoading = true
  107. }
  108. if (forms.id) {
  109. params.id = forms.id
  110. await request.post('/api-school/imMessageBatchSending/update', {
  111. hideLoading: false,
  112. data: params
  113. })
  114. } else {
  115. await request.post('/api-school/imMessageBatchSending/save', {
  116. hideLoading: false,
  117. data: params
  118. })
  119. }
  120. router.back()
  121. forms.sureLoading = false
  122. forms.updateLoading = false
  123. } catch {
  124. //
  125. forms.sureLoading = false
  126. forms.updateLoading = false
  127. }
  128. }
  129. const getDetails = async () => {
  130. try {
  131. if (!forms.id) return
  132. const { data } = await request.get('/api-school/imMessageBatchSending/detail/' + forms.id)
  133. forms.sendType = data.sendType
  134. forms.textMessage = data.textMessage
  135. forms.sendTime = data.sendTime
  136. forms.type = data.sendStatus
  137. const receives = data.receives || []
  138. const tempList: any = {
  139. class: [] as any,
  140. teacher: [] as any,
  141. student: [] as any,
  142. school: [] as any
  143. }
  144. receives.forEach((item: any) => {
  145. const temp = {
  146. receiveType: item.receiveType,
  147. receiveId: item.receiveId,
  148. receiveName: item.receiveName,
  149. avatar: item.avatar
  150. }
  151. forms.receives.push(temp)
  152. const temp2 = {
  153. id: item.receiveId,
  154. value: item.receiveName,
  155. avatar: item.avatar
  156. }
  157. if (item.receiveType === 'CLASS') {
  158. tempList.class.push(temp2)
  159. } else if (item.receiveType === 'STUDENT') {
  160. tempList.student.push(temp2)
  161. } else if (item.receiveType === 'TEACHER') {
  162. tempList.teacher.push(temp2)
  163. } else if (item.receiveType === 'SCHOOL') {
  164. tempList.school.push(temp2)
  165. }
  166. })
  167. forms.selectList = tempList
  168. const attachments = data.attachments || []
  169. const tempAtt: any = []
  170. attachments.forEach((item: any) => {
  171. tempAtt.push(item.imgUrl || item.imgMessage)
  172. })
  173. forms.attachments = tempAtt
  174. } catch (e: any) {
  175. //
  176. console.log(e, 'e')
  177. }
  178. }
  179. // 判断是否是查看
  180. const formDisabled = computed(() => forms.type === 'SEND')
  181. const onClose = async () => {
  182. try {
  183. forms.closeLoading = true
  184. await request.post('/api-school/imMessageBatchSending/remove', {
  185. requestType: 'form',
  186. hideLoading: false,
  187. data: {
  188. id: forms.id
  189. }
  190. })
  191. setTimeout(() => {
  192. showToast('撤销成功')
  193. }, 100)
  194. setTimeout(() => {
  195. // router.replace('/mass-message')
  196. router.back()
  197. forms.closeLoading = false
  198. }, 1100)
  199. } catch {
  200. //
  201. forms.closeLoading = false
  202. }
  203. }
  204. onMounted(() => {
  205. getDetails()
  206. })
  207. return () => (
  208. <div class={styles['create-message']}>
  209. <OHeader />
  210. <CellGroup inset class={styles.cellGroup}>
  211. <Field
  212. inputAlign="right"
  213. label="发送方式"
  214. modelValue={sendType[forms.sendType]}
  215. placeholder="请选择发送方式"
  216. onClick={() => {
  217. if (formDisabled.value) return
  218. forms.sendStatus = true
  219. }}
  220. readonly
  221. isLink={!formDisabled.value}
  222. class={styles.inputForm}
  223. />
  224. {/* 定时发送才会有时间 */}
  225. {forms.sendType === 'SCHEDULED' && (
  226. <Field
  227. inputAlign="right"
  228. label="发送时间"
  229. modelValue={forms.sendTime}
  230. placeholder="请选择发送时间"
  231. onClick={() => {
  232. if (formDisabled.value) return
  233. forms.sendTimeStatus = true
  234. }}
  235. readonly
  236. isLink
  237. class={styles.inputForm}
  238. />
  239. )}
  240. <Cell title="发送内容">
  241. {{
  242. label: () => (
  243. <Field
  244. style={{ padding: '0', marginTop: '12px' }}
  245. placeholder="请输入发送内容"
  246. v-model={forms.textMessage}
  247. type="textarea"
  248. rows={3}
  249. showWordLimit
  250. maxlength={400}
  251. readonly={formDisabled.value}
  252. />
  253. )
  254. }}
  255. </Cell>
  256. <Cell title="上传附件">
  257. {{
  258. label: () => (
  259. <OUploadAll
  260. v-model:modelValue={forms.attachments}
  261. maxCount={9}
  262. bucket={forms.bucket}
  263. disabled={formDisabled.value}
  264. />
  265. )
  266. }}
  267. </Cell>
  268. <Field
  269. label="发送对象"
  270. readonly
  271. inputAlign="right"
  272. class={styles.sendObjPlaceholder}
  273. placeholder={formDisabled.value ? '' : '请选择发送对象'}
  274. isLink={!formDisabled.value}
  275. border={false}
  276. onClick={() => {
  277. if (formDisabled.value) return
  278. forms.selectStatus = true
  279. }}
  280. />
  281. {forms.receives.map((item: any) => {
  282. let img: any = iconStudent
  283. if (item.receiveType === 'CLASS') {
  284. img = iconJiaoFu
  285. } else if (item.receiveType === 'STUDENT') {
  286. img = iconStudent
  287. } else if (item.receiveType === 'TEACHER' || item.receiveType === 'SCHOOL') {
  288. img = iconTeacher
  289. }
  290. return (
  291. <Cell class={styles.receives} title={item.receiveName} center border={false}>
  292. {{
  293. icon: () => <Image class={styles.img} src={item.avatar || img} />,
  294. extra: () =>
  295. !formDisabled.value && (
  296. <Icon
  297. name="clear"
  298. color="#d7d7d7"
  299. size={20}
  300. onClick={() => {
  301. forms.delSelectItem = item
  302. forms.delStatus = true
  303. }}
  304. />
  305. )
  306. }}
  307. </Cell>
  308. )
  309. })}
  310. </CellGroup>
  311. <OSticky position="bottom">
  312. {forms.type === 'ADD' && (
  313. <div class={'btnGroup'}>
  314. <Button round block type="primary" onClick={onSubmit} disabled={forms.sureLoading}>
  315. 确认发送
  316. </Button>
  317. </div>
  318. )}
  319. {forms.type === 'WAIT' && (
  320. <div class={['btnGroup', 'btnMore']}>
  321. <Button round type="primary" onClick={onSubmit} disabled={forms.updateLoading}>
  322. 修改
  323. </Button>
  324. <Button round color="#64A9FF" onClick={onClose} disabled={forms.closeLoading}>
  325. 撤销
  326. </Button>
  327. </div>
  328. )}
  329. </OSticky>
  330. <OActionSheet
  331. v-model:show={forms.sendStatus}
  332. actions={forms.actions}
  333. onSelect={(val: any) => {
  334. forms.actions.forEach((child: any) => {
  335. child.selected = false
  336. })
  337. val.selected = true
  338. forms.sendType = val.value
  339. forms.sendStatus = false
  340. }}
  341. />
  342. <Popup
  343. v-model:show={forms.sendTimeStatus}
  344. position="bottom"
  345. round
  346. class={'popupBottomSearch'}
  347. >
  348. <PickerGroup
  349. title="发送时间"
  350. tabs={['选择日期', '选择时间']}
  351. onCancel={() => (forms.sendTimeStatus = false)}
  352. onConfirm={(val: any) => {
  353. const first = val[0].selectedValues.join('-')
  354. const second = val[1].selectedValues.join(':')
  355. forms.sendTime = dayjs(first + ' ' + second).format('YYYY-MM-DD HH:mm:ss')
  356. forms.sendTimeStatus = false
  357. }}
  358. >
  359. <DatePicker
  360. minDate={new Date()}
  361. maxDate={forms.maxDate}
  362. v-model={forms.currentDate}
  363. formatter={formatterDatePicker}
  364. />
  365. <TimePicker
  366. v-model={forms.currentTime}
  367. formatter={(type: any, option: any) => {
  368. if (type === 'hour') {
  369. option.text += '时'
  370. }
  371. if (type === 'minute') {
  372. option.text += '分'
  373. }
  374. return option
  375. }}
  376. />
  377. </PickerGroup>
  378. </Popup>
  379. <OPopup v-model:modelValue={forms.selectStatus}>
  380. <SelectSned
  381. v-model:selectList={forms.selectList}
  382. onClose={() => (forms.selectStatus = false)}
  383. onConfirm={(val: any) => {
  384. const classList = val.class || []
  385. const studentList = val.student || []
  386. const teacherList = val.teacher || []
  387. const schoolList = val.school || []
  388. const tempList: any = []
  389. classList.forEach((item: any) => {
  390. tempList.push({
  391. receiveType: 'CLASS',
  392. receiveId: item.id,
  393. receiveName: item.value,
  394. avatar: item.avatar
  395. })
  396. })
  397. studentList.forEach((item: any) => {
  398. tempList.push({
  399. receiveType: 'STUDENT',
  400. receiveId: item.id,
  401. receiveName: item.value,
  402. avatar: item.avatar
  403. })
  404. })
  405. teacherList.forEach((item: any) => {
  406. tempList.push({
  407. receiveType: 'TEACHER',
  408. receiveId: item.id,
  409. receiveName: item.value,
  410. avatar: item.avatar
  411. })
  412. })
  413. schoolList.forEach((item: any) => {
  414. tempList.push({
  415. receiveType: 'SCHOOL',
  416. receiveId: item.id,
  417. receiveName: item.value,
  418. avatar: item.avatar
  419. })
  420. })
  421. forms.receives = tempList
  422. }}
  423. />
  424. </OPopup>
  425. <ODialog
  426. v-model:show={forms.delStatus}
  427. showCancelButton
  428. message="您是否删除该数据"
  429. onConfirm={() => {
  430. const selectList = forms.selectList
  431. if (forms.delSelectItem.receiveType === 'CLASS') {
  432. const tempClass = selectList.class || []
  433. const sIndex = tempClass.findIndex(
  434. (item: any) => item.id === forms.delSelectItem.receiveId
  435. )
  436. tempClass.splice(sIndex, 1)
  437. } else if (forms.delSelectItem.receiveType === 'SCHOOL') {
  438. const tempSchool = selectList.school || []
  439. const sIndex = tempSchool.findIndex(
  440. (item: any) => item.id === forms.delSelectItem.receiveId
  441. )
  442. tempSchool.splice(sIndex, 1)
  443. } else if (forms.delSelectItem.receiveType === 'TEACHER') {
  444. const tempTeacher = selectList.teacher || []
  445. const sIndex = tempTeacher.findIndex(
  446. (item: any) => item.id === forms.delSelectItem.receiveId
  447. )
  448. tempTeacher.splice(sIndex, 1)
  449. } else if (forms.delSelectItem.receiveType === 'STUDENT') {
  450. const tempStudent = selectList.student || []
  451. const sIndex = tempStudent.findIndex(
  452. (item: any) => item.id === forms.delSelectItem.receiveId
  453. )
  454. tempStudent.splice(sIndex, 1)
  455. }
  456. forms.selectList = selectList
  457. console.log(forms.selectList, 'forms.selectList')
  458. const index = forms.receives.findIndex(
  459. (item: any) => item.receiveId === forms.delSelectItem.receiveId
  460. )
  461. forms.receives.splice(index, 1)
  462. }}
  463. />
  464. </div>
  465. )
  466. }
  467. })