suggestion-option.tsx 11 KB

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