special-application.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <template>
  2. <view class="page-container ">
  3. <u-nav-bar title="特别申请" bg="#007aff" ref="uNavBar" />
  4. <view class="u-bg" />
  5. <view class="u-disabled-mask" v-if="false" />
  6. <view class="main-content">
  7. <u-panel v-if="form.notice">
  8. <u-des-row label="注意事项" />
  9. <view class="notice-tip" v-html="form.notice" />
  10. </u-panel>
  11. <u-panel>
  12. <u-des-row label="姓名" :value="userInfo.studentName" border />
  13. <u-des-row label="性别" :value="userInfo.genderName" border />
  14. <u-des-row label="班级" :value="userInfo.gradeName" border />
  15. <u-des-row label="学号" :value="userInfo.studentNO" border />
  16. <u-des-row label="联系电话" eye>
  17. <view slot="value" slot-scope="{isOpen}">
  18. {{isOpen ? userInfo.mobileNo : hideCode(userInfo.mobileNo, 3,4) }}
  19. </view>
  20. </u-des-row>
  21. </u-panel>
  22. <u-panel>
  23. <u-des-row label="绩点" :value="form.avgScore.toFixed(2)" border />
  24. <u-des-row label="专业群排名" :value="form.avgScoreRank" border />
  25. <u-picker v-model="form.majorId" label-key="majorName" value-key="majorId" :options="majorOptions">
  26. <u-des-row slot-scope="{data}" label="申请专业" :value="data.majorName || '请选择'"
  27. :style="{opacity: data.majorName?1:0.5}" border />
  28. </u-picker>
  29. <u-des-row label="申请原因" />
  30. <uni-easyinput type="textarea" autoHeight :maxlength="300" v-model="form.applyReason" placeholder="请输入详细的申请原因哦(最多300字)~">
  31. </uni-easyinput>
  32. </u-panel>
  33. <u-panel style="padding-top:24rpx;">
  34. <!-- <u-des-row label="附件" :value="form.attachmentList.length + '/9'" /> -->
  35. <uni-file-picker v-model="form.attachmentList" @select="imgSelect" fileMediatype="image"
  36. file-extname="png,jpg" :auto-upload="false" mode="grid" :limit="9" title="附件">
  37. <view class="choose-image u-flex-center">
  38. <image src="/static/upload_icon.png" style="width: 70rpx;height: 60rpx;" mode=""></image>
  39. <view class="choose-image-tip">上传图片</view>
  40. </view>
  41. </uni-file-picker>
  42. </u-panel>
  43. <u-panel>
  44. <u-des-row label="学生签名" @click="toSign(1)">
  45. <image slot="value" style="width: 34rpx;height: 30rpx;" src="/static/sign_icon.png"
  46. mode="widthFix" />
  47. </u-des-row>
  48. <view v-if="form.studentSign" class="u-sign-preview">
  49. <image :src="form.studentSign" style="width: 100%;height: 100%;" mode="widthFix"></image>
  50. <view class="icon-clear u-flex-center" @click="form.studentSign=''">
  51. <uni-icons type="closeempty" size="15" color="white" />
  52. </view>
  53. </view>
  54. <view v-else class="sign-tip">填写完信息请点击签字笔完成签名哦~</view>
  55. </u-panel>
  56. <view class="u-flex" style="margin: 96rpx 0 32rpx;">
  57. <view class="u-button save-button" :class="{'disabled':disabledSave}" @click="!disabledSave && onSumbit(1)">
  58. 暂存
  59. </view>
  60. <view style="width:20rpx">
  61. </view>
  62. <button class="u-button sumbit-button" :class="{'disabled':disabledSumbit}" @click="!disabledSumbit && onSumbit(2)">
  63. {{form.applyStatus >= 1 ? '已提交' : '提交'}}
  64. </button>
  65. </view>
  66. </view>
  67. <u-drawer :visible.sync="visible" title="手写签名" @sumbit="signSumbit" @cancel="visible=false">
  68. <view v-if="false" class="drawer-tip">
  69. <text class="empty-2"></text>
  70. <text>本人已仔细阅读专业分流并理解了有关要求和规定,在此我郑重承诺:“本人自愿按以上顺序选择专业,服从调剂,且专业分流后不再变更。
  71. 对违反以上承诺所造成的后果,本人自愿承担相应责任。”</text>
  72. </view>
  73. <u-sign ref="uSign" v-if="visible" />
  74. </u-drawer>
  75. </view>
  76. </template>
  77. <script>
  78. import {
  79. mapState
  80. } from 'vuex'
  81. import {
  82. hideCode
  83. } from '@/common'
  84. import formChecker from '@/common/formChecker.js'
  85. export default {
  86. data() {
  87. return {
  88. majorOptions: [], // majorId majorName
  89. form: {
  90. notice: '',
  91. majorId: '',
  92. majorName: '',
  93. applyReason: '',
  94. attachmentList: [],
  95. studentSign: '',
  96. specialApplyId: '',
  97. applyStatus: '', //0未提交 1已提交 2通过 3驳回
  98. },
  99. signType: '',
  100. visible: false // 签名 抽屉
  101. }
  102. },
  103. computed: {
  104. ...mapState({
  105. userInfo: state => state.user.userInfo,
  106. }),
  107. disabledSave() {
  108. return this.form.applyStatus >= 1 // 已提交
  109. },
  110. disabledSumbit() {
  111. return this.form.applyStatus >= 1 || !this.form.specialApplyId // 已提交 或 未缓存
  112. }
  113. },
  114. mounted() {
  115. this.$ajax.get('/shunt/major-info').then(res => {
  116. this.majorOptions = res.data || []
  117. })
  118. this.init()
  119. },
  120. methods: {
  121. hideCode,
  122. async init() {
  123. // 特别申请浏览
  124. this.$ajax.post('/shunt/special-apply-view').then(res => {
  125. let attachmentList = res.data.attachmentList || []
  126. attachmentList = attachmentList.map(item => {
  127. return {
  128. path: item,
  129. url: item,
  130. }
  131. })
  132. Object.assign(this.form, res.data, {
  133. attachmentList
  134. })
  135. console.log(111, this.form)
  136. })
  137. },
  138. imgSelect(res) {
  139. let error2M = 0
  140. const newImgs = res.tempFiles.filter(file => {
  141. const isLt2M = file.size / 1024 / 1024 < 2
  142. if(!isLt2M) {
  143. error2M++
  144. }
  145. return isLt2M
  146. })
  147. if (error2M) {
  148. uni.showToast({
  149. title: `当前选择了${res.tempFiles.length}个文件,${error2M}个文件大于2M`,
  150. icon: "none"
  151. });
  152. }
  153. console.log(111, newImgs)
  154. this.form.attachmentList = this.form.attachmentList.concat(newImgs)
  155. },
  156. toSign(type) { // 1学生 2家长
  157. this.signType = type
  158. this.visible = true
  159. },
  160. signSumbit() {
  161. this.$refs.uSign.getBase64(res => {
  162. if (this.signType === 1) {
  163. this.form.studentSign = res?.tempFilePath || ''
  164. } else {
  165. this.form.test7 = res?.tempFilePath || ''
  166. }
  167. this.visible = false
  168. })
  169. },
  170. // api
  171. async onSumbit(type) { // 1:暂存 2:提交
  172. //定义表单规则
  173. var rule = [
  174. // {
  175. // name: "avgScore",
  176. // checkType: "notnull",
  177. // errorMsg: "请输入绩点"
  178. // }, {
  179. // name: "avgScoreRank",
  180. // checkType: "notnull",
  181. // errorMsg: "请输入专业群排名"
  182. // },
  183. //
  184. {
  185. name: "majorId",
  186. checkType: "notnull",
  187. errorMsg: "请输入申请专业"
  188. }, {
  189. name: "applyReason",
  190. checkType: "notnull",
  191. errorMsg: "请输入申请原因"
  192. }, {
  193. name: "attachmentList",
  194. checkType: "notnull",
  195. errorMsg: "请添加附件"
  196. }, {
  197. name: "studentSign",
  198. checkType: "notnull",
  199. errorMsg: "请填写学生签名"
  200. }
  201. ];
  202. //进行表单检查
  203. var checkRes = formChecker.check(this.form, rule);
  204. if (!checkRes) {
  205. uni.showToast({
  206. title: formChecker.error,
  207. icon: "none"
  208. });
  209. return
  210. }
  211. await this.uploadFiles()
  212. const that = this
  213. uni.showLoading()
  214. const params = {
  215. ...that.form
  216. }
  217. params.attachmentList = params.attachmentList.map(item => item.path)
  218. that.$ajax.post('/shunt/special-apply', params).then(res => {
  219. if (type === 1) {
  220. uni.showToast({
  221. title: '暂存成功',
  222. icon: "success"
  223. });
  224. that.init()
  225. }
  226. uni.hideLoading()
  227. }).catch(error => {
  228. uni.hideLoading()
  229. uni.showModal({
  230. title: '错误',
  231. content: error.msg || error,
  232. showCancel: false
  233. })
  234. })
  235. if (type === 2) {
  236. uni.showLoading()
  237. that.$ajax.post('/shunt/special-apply-submit').then(res => {
  238. uni.showToast({
  239. title: '提交成功',
  240. icon: "success"
  241. });
  242. that.init()
  243. uni.hideLoading()
  244. }).catch(error => {
  245. uni.hideLoading()
  246. uni.showModal({
  247. title: '错误',
  248. content: error.msg || error,
  249. showCancel: false
  250. })
  251. })
  252. }
  253. },
  254. async uploadFiles(success) {
  255. uni.showLoading({
  256. title: '上传文件中...'
  257. });
  258. const promiseList = []
  259. const indexList = []
  260. const that = this
  261. that.form.attachmentList.forEach((element, index) => {
  262. if (element.status) {
  263. indexList.push(index)
  264. promiseList.push(uni.uploadFile({
  265. url: `/shunt/upload`,
  266. filePath: element.url,
  267. // fileType: 'image',
  268. name: 'file',
  269. header: {
  270. token: uni.getStorageSync('TOKEN')
  271. },
  272. formData: {
  273. // file: res.tempFiles[0],
  274. fileType: 'APPLY',
  275. },
  276. // success(uploadFileRes) {
  277. // const data = JSON.parse(uploadFileRes.data)
  278. // const filePath = data.data.filePath
  279. // console.log(1111, filePath)
  280. // that.form.attachmentList[index] = filePath
  281. // }
  282. }))
  283. }
  284. })
  285. await Promise.all(promiseList).then(resList => {
  286. resList.forEach((element, index) => {
  287. let uploadFileRes = element[1]
  288. const data = JSON.parse(uploadFileRes.data)
  289. const filePath = data.data.filePath
  290. const formIndex = indexList[index]
  291. that.form.attachmentList[formIndex].path = filePath
  292. })
  293. })
  294. uni.hideLoading()
  295. }
  296. }
  297. }
  298. </script>
  299. <style lang="scss" scoped>
  300. .page-container {
  301. .u-bg {
  302. height: 317rpx;
  303. background: $uni-color-primary;
  304. }
  305. .main-content {
  306. padding: 60rpx 32rpx 32rpx 32rpx;
  307. }
  308. .notice-tip {
  309. font-size: 24rpx;
  310. font-weight: 400;
  311. color: #999999;
  312. line-height: 1.5;
  313. padding-bottom: 32rpx;
  314. }
  315. .sign-tip {
  316. height: 144rpx;
  317. font-size: 20rpx;
  318. font-weight: 400;
  319. color: #A3ABBF;
  320. }
  321. .drawer-tip {
  322. font-size: 24rpx;
  323. font-weight: 400;
  324. line-height: 1.5;
  325. color: #999999;
  326. margin-bottom: 36rpx;
  327. }
  328. .save-button,
  329. .sumbit-button {
  330. flex: 1;
  331. height: 88rpx;
  332. background: linear-gradient(90deg, #FFCF18 0%, #FFB300 100%);
  333. border-radius: 8rpx;
  334. &.disabled {
  335. cursor: not-allowed;
  336. opacity: 0.3;
  337. }
  338. }
  339. .sumbit-button {
  340. background: linear-gradient(90deg, #36ACFC 0%, #078EF7 100%);
  341. }
  342. .choose-image {
  343. width: 100%;
  344. height: 100%;
  345. background: #FFFFFF;
  346. cursor: pointer;
  347. text-align: center;
  348. border: 1rpx dashed #A3ABBF;
  349. flex-direction: column;
  350. .choose-image-tip {
  351. font-size: 24rpx;
  352. font-weight: 400;
  353. color: #078EF7;
  354. margin-top: 24rpx;
  355. }
  356. }
  357. }
  358. </style>