suggestion-option.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. import { defineComponent, onMounted, reactive, ref } from 'vue';
  2. import styles from './suggestion-option.module.less';
  3. import {
  4. NButton,
  5. NForm,
  6. NFormItem,
  7. NInput,
  8. NSelect,
  9. NSpace,
  10. useMessage,
  11. NUpload,
  12. UploadFileInfo,
  13. NImage
  14. } from 'naive-ui';
  15. import { useUserStore } from '/src/store/modules/users';
  16. import bgLine from '../images/bg-line.png';
  17. import chioseAdd from '../images/chioseAdd.png';
  18. import CSelect from '../../CSelect';
  19. import { policy } from '../../upload-file/api';
  20. import suggestClose from '../images/suggestClose.png';
  21. import inFront from '../images/inFront.png';
  22. import inBack from '../images/inBack.png';
  23. import submitBtn from '../images/submitBtn.png';
  24. import sealing from '../images/sealing.png'
  25. import boxBg from '../images/boxBg.png'
  26. import {
  27. addSuggestion,
  28. getSuggestionList,
  29. sysParamConfigPage
  30. } from '../modals/api';
  31. import { nextTick } from 'process';
  32. export default defineComponent({
  33. name: 'train-update',
  34. emits: ['close', 'submit'],
  35. setup(props, { emit,expose }) {
  36. const message = useMessage();
  37. const userStore = useUserStore();
  38. const forms = reactive({
  39. suggestionTypeId: null,
  40. clientType: 'TEACHER',
  41. content: '',
  42. attachmentUrls: '',
  43. type: 'APP',
  44. mobileNo: userStore.getUserInfo.phone
  45. });
  46. const state = reactive([]) as any;
  47. const isubmit = ref(false)
  48. const suggestionTypeList = ref([] as any);
  49. const ossUploadUrl = `https://gyt.ks3-cn-beijing.ksyuncs.com/`;
  50. const uploadRef = ref();
  51. const fileListRef = ref<UploadFileInfo[]>([]);
  52. const formsRef = ref();
  53. const btnLoading = ref(false);
  54. const tempFiileBuffer = ref();
  55. const email = ref('');
  56. const phone = ref('');
  57. const isLoading = ref(false)
  58. const ishidden= ref(false)
  59. const onSubmit = async () => {
  60. // if (!forms.suggestionTypeId) {
  61. // message.error('请选择反馈类型');
  62. // return;
  63. // }
  64. // if (!forms.content) {
  65. // message.error('请填写反馈信息');
  66. // return;
  67. // }
  68. formsRef.value?.validate(async (err: any) => {
  69. if (err) {
  70. return;
  71. }
  72. const attachmentUrlsList = fileListRef.value.map((item: any) => {
  73. console.log(item, 'item');
  74. const name = item.name;
  75. // const suffix = name.slice(name.lastIndexOf('.'));
  76. const fileName = `${item.id + name}`;
  77. const url = ossUploadUrl + fileName;
  78. return url;
  79. });
  80. const attachmentUrls = attachmentUrlsList.join(',');
  81. try {
  82. const res = await addSuggestion({ ...forms, attachmentUrls });
  83. isubmit.value = true;
  84. // message.success('提交成功');
  85. setTimeout(()=>{
  86. onReset()
  87. ishidden.value = true
  88. emit('close')
  89. },3000)
  90. } catch (e) {
  91. console.log(e);
  92. }
  93. console.log('onSubmit');
  94. })
  95. };
  96. const onReset = ()=>{
  97. ishidden.value = false
  98. isubmit.value = false
  99. forms.suggestionTypeId=null
  100. forms.clientType='TEACHER'
  101. forms.content= ''
  102. forms.attachmentUrls= ''
  103. fileListRef.value = [];
  104. forms.type= 'APP'
  105. forms.mobileNo= userStore.getUserInfo.phone
  106. }
  107. expose({onReset})
  108. const onBeforeUpload = async (options: any) => {
  109. console.log(options, 'onBeforeUpload');
  110. const file = options.file;
  111. // 文件大小
  112. let isLt2M = true;
  113. const size = 2;
  114. if (size) {
  115. isLt2M = file.file.size / 1024 / 1024 < size;
  116. if (!isLt2M) {
  117. message.error(`文件大小不能超过${size}M`);
  118. return false;
  119. }
  120. }
  121. if (!isLt2M) {
  122. return isLt2M;
  123. }
  124. // 是否裁切
  125. try {
  126. btnLoading.value = true;
  127. const name = file.file.name;
  128. const fileName = `${file.id + name}`;
  129. const obj = {
  130. filename: fileName,
  131. bucketName: 'gyt',
  132. postData: {
  133. filename: fileName,
  134. acl: 'public-read',
  135. key: fileName,
  136. unknowValueField: []
  137. }
  138. };
  139. const { data } = await policy(obj);
  140. state.push({
  141. id: file.id,
  142. tempFiileBuffer: file.file,
  143. policy: data.policy,
  144. signature: data.signature,
  145. acl: 'public-read',
  146. key: fileName,
  147. KSSAccessKeyId: data.kssAccessKeyId,
  148. name: fileName
  149. });
  150. } catch {
  151. //
  152. // message.error('上传失败')
  153. btnLoading.value = false;
  154. return false;
  155. }
  156. return true;
  157. };
  158. const onFinish = (options: any) => {
  159. // const url =
  160. const name = options.file.name;
  161. // const suffix = name.slice(name.lastIndexOf('.'));
  162. const fileName = `${options.file.id + name}`;
  163. const url = ossUploadUrl + fileName;
  164. // urlList.value.push(url);
  165. // onFinishAfter(options);
  166. };
  167. const onRemove = async (event: any) => {
  168. console.log(event);
  169. btnLoading.value = false;
  170. };
  171. const getTypeList = async () => {
  172. try {
  173. const res = await getSuggestionList({ rows: 9999, page: 1 });
  174. suggestionTypeList.value = res.data.rows;
  175. } catch (e) {
  176. console.log(e);
  177. }
  178. };
  179. const getPhoneInfo = async () => {
  180. try {
  181. const { data } = await sysParamConfigPage({
  182. page: 1,
  183. rows: 999,
  184. group: 'OTHER'
  185. });
  186. const rows = data.rows || [];
  187. email.value = rows.find((item: any) => {
  188. return item.paramName == 'customer_service_email';
  189. }).paramValue;
  190. phone.value = rows.find((item: any) => {
  191. return item.paramName == 'customer_service_phone';
  192. }).paramValue;
  193. console.log(email.value, phone.value);
  194. } catch (e) {
  195. console.log('请求报错');
  196. console.log(e);
  197. }
  198. };
  199. const imglist = [inFront,inBack,submitBtn,sealing,boxBg]
  200. const loadImg = (imgList:any) => {
  201. for (let i = 0; i < imgList.length; i++) {
  202. const img = new Image()
  203. // let currentSrc = ''
  204. img.src = imgList[i]
  205. img.onload = function (e) {
  206. console.log('加载完毕', e,img.complete );
  207. }
  208. img.onerror = function (e) {
  209. console.log('加载错误', e);
  210. }
  211. }
  212. }
  213. loadImg(imglist)
  214. onMounted(() => {
  215. getTypeList();
  216. getPhoneInfo();
  217. });
  218. return () => (
  219. <div class={[styles.suggestOption]}>
  220. <div class={[styles.updatePassword,isubmit.value?styles.isAni:'',ishidden.value?styles.isend:null]}>
  221. <div class={[styles.formWrap,isubmit.value?styles.isAni:'']}>
  222. <NImage
  223. class={styles.closeBtn}
  224. src={suggestClose}
  225. previewDisabled onClick={() => {onReset();emit('close')}}></NImage>
  226. <NImage class={styles.bgLine} src={bgLine} previewDisabled></NImage>
  227. <h2 class={styles.formTitle}>意见反馈</h2>
  228. <div class={styles.formWrapInfo}>
  229. <NForm
  230. labelAlign="right"
  231. labelPlacement="left"
  232. labelWidth={'auto'}
  233. ref={formsRef}
  234. model={forms}
  235. requireMarkPlacement="left">
  236. {/* <NFormItem
  237. path="currentClass"
  238. label=""
  239. class={styles.phoneContainer}>
  240. <p class={styles.phone}>{forms.mobile}</p>
  241. </NFormItem> */}
  242. <NFormItem
  243. rule={[
  244. {
  245. required: true,
  246. message: '请选择反馈类型'
  247. }
  248. ]}
  249. path="suggestionTypeId">
  250. <CSelect
  251. class={styles.suggestSelect}
  252. value-field="id"
  253. label-field="name"
  254. style={{ width: '227px!important' }}
  255. {...({
  256. options: suggestionTypeList.value,
  257. placeholder: '反馈类型(必选)',
  258. clearable: true,
  259. inline: true
  260. } as any)}
  261. v-model:value={forms.suggestionTypeId}></CSelect>
  262. </NFormItem>
  263. <NFormItem
  264. path="content"
  265. rule={[
  266. {
  267. required: true,
  268. message: '请输入反馈内容'
  269. }
  270. ]}>
  271. <NInput
  272. class={styles.countInput}
  273. type="textarea"
  274. rows={5}
  275. placeholder={'请输入反馈内容'}
  276. maxlength={200}
  277. resizable={false}
  278. showCount
  279. v-model:value={forms.content}></NInput>
  280. </NFormItem>
  281. <NFormItem>
  282. <NUpload
  283. list-type="image-card"
  284. accept=".jpg,jpeg,.png"
  285. v-model:fileList={fileListRef.value}
  286. ref={uploadRef}
  287. multiple={true}
  288. max={5}
  289. data={(file: any) => {
  290. const item = state.find((c: any) => {
  291. return c.id == file.file.id;
  292. });
  293. const { id, tempFiileBuffer, ...more } = item;
  294. return { ...more };
  295. }}
  296. showPreviewButton
  297. action={ossUploadUrl}
  298. onBeforeUpload={(options: any) => onBeforeUpload(options)}
  299. onRemove={(options: any) => onRemove(options)}
  300. onFinish={(options: any) => onFinish(options)}>
  301. <div class={styles.addInput}>
  302. <NImage previewDisabled src={chioseAdd}></NImage>
  303. <p> 点击上传图片</p>
  304. <p>(最多五张)</p>
  305. </div>
  306. </NUpload>
  307. </NFormItem>
  308. {/* {phone.value || email.value ? (
  309. <NFormItem>
  310. <div class={styles.messageWrap}>
  311. {phone.value ? <p>客服电话:{phone.value}</p> : null}
  312. {email.value ? <p>邮箱:{email.value}</p> : null}
  313. </div>
  314. </NFormItem>
  315. ) : null} */}
  316. {/* <NSpace class={styles.updateBtnGroup}>
  317. <NButton
  318. strong
  319. type="default"
  320. round
  321. onClick={() => emit('close')}>
  322. 取消
  323. </NButton>
  324. <NButton strong type="primary" round onClick={() => onSubmit()}>
  325. 确认
  326. </NButton>
  327. </NSpace> */}
  328. </NForm>
  329. </div>
  330. </div>
  331. <div class={[styles.inBack,isubmit.value?styles.isAni:'']}>
  332. </div>
  333. {/* <div class={styles.inBackBottom}></div> boxBg */}
  334. <NImage src={boxBg} class={styles.inBackBottom} previewDisabled></NImage>
  335. <NImage src={inFront} class={styles.inFront} previewDisabled></NImage>
  336. <NImage src={sealing} class={[styles.sealing,isubmit.value?styles.isAni:'']} previewDisabled></NImage>
  337. {!isubmit.value?<>
  338. <NImage src={submitBtn} onClick={()=>{onSubmit()}} class={styles.submitBtn} previewDisabled></NImage>
  339. <div class={styles.messageWrap}>
  340. {phone.value ? <p>客服电话:{phone.value}</p> : null}
  341. {email.value ? <p>邮箱:{email.value}</p> : null}
  342. </div>
  343. </>:null}
  344. </div>
  345. </div>
  346. );
  347. }
  348. });