Remuneration.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <template>
  2. <div class="wrap" id="remuneration">
  3. <m-header v-if="headerStatus" />
  4. <div class="monthMoney">{{ appealDate }}课酬 <br/><span>总计:{{ allMoney }}元</span></div>
  5. <div class="monthCount" v-if="statistics.length > 0">
  6. <div class="item" v-for="(item, index) in statistics" :key="index">
  7. <!-- <span class="title" v-if="item.groupType == 'ALL'">本月合计</span> -->
  8. <span class="title" v-if="item.statType == 'MUSIC'">乐团课合计</span>
  9. <span class="title" v-if="item.statType == 'VIP'">VIP课合计</span>
  10. <span class="title" v-if="item.statType == 'PRACTICE'">网管课合计</span>
  11. <span class="title" v-if="item.statType == 'REWARD'">转结奖励合计</span>
  12. <span>{{ item.courseTimes }}{{ item.statType == 'REWARD' ? '组' : '节' }}</span>
  13. <span class="money">{{ item.totalActualSalary }}元</span>
  14. </div>
  15. </div>
  16. <!-- :class="confirmStatus == 0 ? 'paddingB80' : 'paddingB16'" -->
  17. <div :class="confirmStatus == 0 ? 'paddingB80' : 'paddingB16'">
  18. <van-tabs v-model="active">
  19. <van-tab title="课酬明细">
  20. <div v-if="dataShow" key="data">
  21. <van-list v-model="loading" :finished="finished" finished-text=" " @load="getList">
  22. <van-cell-group v-for="(item, index) in dataList" :key="index">
  23. <van-cell>
  24. <template #icon>
  25. <i class="icon icon_audition" v-if="item.groupType == 'PRACTICE'"></i>
  26. <i class="icon icon_vip" v-if="item.groupType == 'VIP'"></i>
  27. <i class="icon icon_music" v-if="item.groupType == 'MUSIC'"></i>
  28. </template>
  29. <template #title>
  30. <div class="title">{{ item.courseName }}</div>
  31. <div class="baseInfo">
  32. <p>排课:{{ item.startClassTime | getMonthDay }} {{ item.startClassTime | getHourMin }}-{{ item.endClassTime | getHourMin }}</p>
  33. <p>签到:{{ item.signInTime | getHourMin }}&nbsp;&nbsp;&nbsp;&nbsp;签退:{{ item.signOutTime | getHourMin }}</p>
  34. </div>
  35. </template>
  36. <template #default>
  37. <p class="money" :class="[item.reduceSalary > 0 ? 'error' : '']">
  38. ¥<span>{{ item.finalSalary }}</span>
  39. </p>
  40. <div class="moneyInfo" v-if="item.reduceSalary > 0">
  41. 课酬:¥{{ item.actualSalary }}
  42. <br />扣款:¥{{ item.reduceSalary }}
  43. </div>
  44. </template>
  45. </van-cell>
  46. </van-cell-group>
  47. </van-list>
  48. </div>
  49. <m-empty class="empty" v-else key="data" />
  50. </van-tab>
  51. <van-tab title="转结奖励明细">
  52. <div v-if="dataShow2" key="data2">
  53. <van-list v-model="loading2" :finished="finished2" finished-text=" " @load="getList2">
  54. <van-cell-group v-for="(item, index) in dataList2" :key="index">
  55. <van-cell>
  56. <template #icon>
  57. <!-- <i class="icon icon_audition" v-if="item.groupType == 'PRACTICE'"></i>
  58. <i class="icon icon_vip" v-if="item.groupType == 'VIP'"></i>
  59. <i class="icon icon_music" v-if="item.groupType == 'MUSIC'"></i> -->
  60. <i class="icon icon_reword"></i>
  61. </template>
  62. <template #title>
  63. <div class="title">{{ item.courseName }}</div>
  64. <div class="baseInfo">
  65. <p>排课:{{ item.startClassTime | getMonthDay }} {{ item.startClassTime | getHourMin }}-{{ item.endClassTime | getHourMin }}</p>
  66. <p>签到:{{ item.signInTime | getHourMin }}&nbsp;&nbsp;&nbsp;&nbsp;签退:{{ item.signOutTime | getHourMin }}</p>
  67. </div>
  68. </template>
  69. <template #default>
  70. <p class="money" :class="[item.reduceSalary > 0 ? 'error' : '']">
  71. ¥<span>{{ item.finalSalary }}</span>
  72. </p>
  73. <div class="moneyInfo" v-if="item.reduceSalary > 0">
  74. 课酬:¥{{ item.actualSalary }}
  75. <br />扣款:¥{{ item.reduceSalary }}
  76. </div>
  77. </template>
  78. </van-cell>
  79. </van-cell-group>
  80. </van-list>
  81. </div>
  82. <m-empty class="empty" v-else key="data2" />
  83. </van-tab>
  84. </van-tabs>
  85. </div>
  86. <!-- <m-empty class="empty" v-else key="data" /> -->
  87. <div class="button-group" v-if="confirmStatus == 0">
  88. <span class="btn" @click="onAppeal(haveComplaints)">{{ haveComplaints == 1 ? '申诉详情' : '问题申诉' }}</span>
  89. <span class="btn primary" @click="onConfirmAppeal">确认课酬</span>
  90. </div>
  91. </div>
  92. </template>
  93. <script>
  94. import MHeader from "@/components/MHeader";
  95. import { browser, getSTD } from "@/common/common";
  96. import MEmpty from "@/components/MEmpty";
  97. import { findTeacherSettlementCourseSalarys, confirmTeacherMonthSalary, findTeacherRewards } from "@/api/audition";
  98. export default {
  99. name: "remuneration",
  100. components: { MHeader, MEmpty },
  101. data() {
  102. let query = this.$route.query
  103. let tempDate = new Date(query.month + '-01')
  104. if(!query.month) {
  105. tempDate = new Date()
  106. tempDate.setMonth(tempDate.getMonth() - 1)
  107. }
  108. let tempAppealDate = tempDate.getFullYear() + '年' + getSTD(tempDate.getMonth() + 1) + '月'
  109. let tempAppealDateStr = tempDate.getFullYear() + '-' + getSTD(tempDate.getMonth() + 1)
  110. return {
  111. active: 0,
  112. headerStatus: true,
  113. appealDate: tempAppealDate,
  114. appealDateStr: tempAppealDateStr,
  115. loading: false,
  116. finished: false,
  117. statistics: [],
  118. allMoney: 0, // 总计金额
  119. dataList: [],
  120. dataShow: true, // 是否有数据
  121. confirmStatus: 1, // 是否确认
  122. haveComplaints: 0, // 是否存在申诉
  123. params: {
  124. month: query.month ? query.month : null,
  125. page: 1,
  126. rows: 20
  127. },
  128. loading2: false,
  129. finished2: false,
  130. dataList2: [],
  131. dataShow2: true, // 是否有数据
  132. params2: {
  133. month: query.month ? query.month : null,
  134. page: 1,
  135. rows: 20
  136. },
  137. };
  138. },
  139. mounted() {
  140. let params = this.$route.query;
  141. if (params.Authorization) {
  142. localStorage.setItem("Authorization", decodeURI(params.Authorization));
  143. localStorage.setItem("userInfo", decodeURI(params.Authorization));
  144. }
  145. document.title = "确认课酬";
  146. if (browser().android || browser().iPhone) {
  147. if(params.isHide == 1) {
  148. this.headerStatus = true
  149. } else {
  150. this.headerStatus = false;
  151. }
  152. }
  153. },
  154. methods: {
  155. getList() {
  156. // this.finished = true
  157. let params = this.params;
  158. findTeacherSettlementCourseSalarys(params).then(res => {
  159. let result = res.data;
  160. this.loading = false;
  161. if (result.code == 200) {
  162. // 判断是否有统计数据
  163. if(result.data.stat && result.data.stat.length > 0) {
  164. this.statistics = result.data.stat
  165. let counts = {
  166. courseTimes: 0,
  167. totalActualSalary: 0
  168. }
  169. result.data.stat.forEach(item => {
  170. counts.courseTimes += item.courseTimes
  171. counts.totalActualSalary += item.totalActualSalary
  172. })
  173. this.allMoney = counts.totalActualSalary
  174. }
  175. let pageInfo = result.data.pageInfo
  176. params.page = pageInfo.pageNo
  177. this.confirmStatus = result.data.confirmStatus
  178. this.haveComplaints = result.data.haveComplaints
  179. this.dataList = this.dataList.concat(pageInfo.rows)
  180. if (params.page >= pageInfo.totalPage) {
  181. this.finished = true;
  182. }
  183. this.params.page++;
  184. } else {
  185. this.finished = true;
  186. }
  187. // 判断是否有数据
  188. if (this.dataList.length <= 0) {
  189. this.dataShow = false;
  190. }
  191. });
  192. },
  193. getList2() {
  194. // this.finished = true
  195. let params = this.params2;
  196. findTeacherRewards(params).then(res => {
  197. let result = res.data;
  198. this.loading2 = false;
  199. if (result.code == 200) {
  200. let pageInfo = result.data
  201. params.page = pageInfo.pageNo
  202. this.dataList2 = this.dataList2.concat(pageInfo.rows)
  203. if (params.page >= pageInfo.totalPage) {
  204. this.finished2 = true;
  205. }
  206. this.params2.page++;
  207. } else {
  208. this.finished2 = true;
  209. }
  210. // 判断是否有数据
  211. if (this.dataList2.length <= 0) {
  212. this.dataShow2 = false;
  213. }
  214. });
  215. },
  216. onAppeal(haveComplaints) {
  217. this.$router.push({
  218. path: "appealDetail",
  219. query: {
  220. haveComplaints: haveComplaints,
  221. appealDateStr: this.appealDateStr
  222. }
  223. });
  224. },
  225. onConfirmAppeal() {
  226. this.$dialog.confirm({
  227. title: '确认课酬',
  228. message: '您是否确认本月课酬?',
  229. })
  230. .then(() => {
  231. // on confirm
  232. confirmTeacherMonthSalary({ month: this.appealDateStr }).then(res => {
  233. let result = res.data
  234. if(result.code == 200) {
  235. this.$toast('课酬确认成功')
  236. this.confirmStatus = 1
  237. document.querySelector('#remuneration').scrollTop = 0
  238. } else {
  239. this.$toast(result.msg)
  240. }
  241. })
  242. })
  243. .catch(() => {
  244. // on cancel
  245. })
  246. }
  247. },
  248. filters: {
  249. getHourMin(time) {
  250. let tempDate = time
  251. if(!time) {
  252. return ''
  253. }
  254. if(typeof(tempDate) == 'string') {
  255. tempDate = new Date(time.replace(/-/ig, '/'))
  256. }
  257. let hour = tempDate.getHours()
  258. let minut = tempDate.getMinutes()
  259. return getSTD(hour) + ':' + getSTD(minut)
  260. },
  261. getMonthDay(time) {
  262. let tempDate = time || new Date()
  263. if(typeof(tempDate) == 'string') {
  264. tempDate = new Date(time.replace(/-/ig, '/'))
  265. }
  266. let month = tempDate.getMonth() + 1
  267. let day = tempDate.getDate()
  268. return month + '月' + day + '日'
  269. }
  270. }
  271. };
  272. </script>
  273. <style lang="less" scoped>
  274. @import url("../../assets/commonLess/variable.less");
  275. .wrap {
  276. min-height: 100vh;
  277. overflow-y: auto;
  278. overflow-x: hidden;
  279. background-color: #f3f4f8;
  280. }
  281. .monthMoney {
  282. font-size: 0.16rem;
  283. color: #1a1a1a;
  284. background: #fff;
  285. text-align: center;
  286. padding: .1rem 0;
  287. span {
  288. font-size: .18rem;
  289. }
  290. }
  291. .monthCount {
  292. border: 1px solid rgba(204, 204, 204, 1);
  293. border-radius: 0.04rem;
  294. margin: 0.16rem 0.16rem .12rem;
  295. background: #fff;
  296. padding: 0.12rem;
  297. .item {
  298. display: flex;
  299. justify-content: space-between;
  300. color: #666666;
  301. font-size: 0.14rem;
  302. padding: 0.05rem 0.1rem;
  303. .title {
  304. width: 1rem;
  305. }
  306. .money {
  307. width: 0.8rem;
  308. text-align: right;
  309. }
  310. &:nth-child(2n + 2) {
  311. background: #f0f0f0;
  312. }
  313. }
  314. }
  315. /deep/.van-tabs {
  316. background: #fff;
  317. padding-bottom: .12rem;
  318. }
  319. /deep/.van-tabs__line {
  320. background-color: #14928A;
  321. }
  322. /deep/.van-cell-group {
  323. margin: 0.16rem 0.16rem 0;
  324. border: 1px solid #71bdb8;
  325. border-radius: 0.04rem;
  326. overflow: hidden;
  327. }
  328. /deep/.van-cell {
  329. padding: 0.13rem;
  330. .van-cell__title {
  331. padding-left: 0.1rem;
  332. }
  333. .van-cell__value {
  334. flex: 0 auto;
  335. padding-left: 0.1rem;
  336. }
  337. .title {
  338. font-size: 0.16rem;
  339. font-weight: 500;
  340. color: #1a1a1a;
  341. padding-bottom: 0.05rem;
  342. }
  343. .baseInfo {
  344. font-size: 0.14rem;
  345. color: #808080;
  346. line-height: 1.3;
  347. }
  348. .money {
  349. font-size: 0.16rem;
  350. color: #1a1a1a;
  351. padding-bottom: 0.02rem;
  352. line-height: .24rem;
  353. &.error {
  354. color: #ff3535;
  355. }
  356. span {
  357. font-size: 0.22rem;
  358. }
  359. }
  360. .moneyInfo {
  361. font-size: 0.14rem;
  362. line-height: 1.3;
  363. color: #1a1a1a;
  364. }
  365. }
  366. .icon {
  367. width: 0.4rem;
  368. height: 0.4rem;
  369. display: inline-block;
  370. }
  371. .icon_audition {
  372. background: url("../../assets/images/audition/audition_icon.png") no-repeat
  373. center;
  374. background-size: contain;
  375. }
  376. .icon_music {
  377. background: url("../../assets/images/audition/music_icon.png") no-repeat
  378. center;
  379. background-size: contain;
  380. }
  381. .icon_vip {
  382. background: url("../../assets/images/audition/vip_icon.png") no-repeat center;
  383. background-size: contain;
  384. }
  385. .icon_reword {
  386. background: url("../../assets/images/audition/reword_icon.png") no-repeat center;
  387. background-size: contain;
  388. }
  389. .paddingB80 {
  390. padding-bottom: .8rem
  391. }
  392. .paddingB16 {
  393. padding-bottom: .16rem;
  394. }
  395. .button-group {
  396. position: fixed;
  397. bottom: 0;
  398. margin: 0.2rem 0;
  399. width: 100%;
  400. text-align: center;
  401. .btn {
  402. padding: 0 0.45rem;
  403. line-height: 0.4rem;
  404. display: inline-block;
  405. border: 1px solid @mColor;
  406. border-radius: 1rem;
  407. color: @mColor;
  408. background: #fff;
  409. font-size: 0.18rem;
  410. &.primary {
  411. color: #fff;
  412. background: @mColor;
  413. }
  414. }
  415. .btn + .btn {
  416. margin-left: 0.1rem;
  417. }
  418. }
  419. </style>