tansferDuration.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <div class="transfer">
  3. <div>
  4. <div>减少时长的云机</div>
  5. <div>
  6. <comoros :key="transferUserCardKey" :dayTime="countObj.transferMinDay" :transferPhoneList="transferPhoneList" :buyVipType.sync="buyVipType"
  7. v-model="params.transferUserCardId" :name.sync="transferUserCardName" @confirm="comorosConfirm" />
  8. </div>
  9. </div>
  10. <div class="transfer-item">
  11. <div>增加时长的云机</div>
  12. <div>
  13. <comoros :key="acceptUserCardKey" :disabledId="params.transferUserCardId"
  14. :transferPhoneList="transferPhoneList" :filterType="buyVipType" v-model="params.acceptUserCardId"
  15. :name.sync="acceptUserCardName" distinguishBool/>
  16. </div>
  17. </div>
  18. <div class="transfer-item">
  19. <div>转移的时间</div>
  20. <div class="transfer-item-input">
  21. <van-field placeholder="请输入转移的时间" v-model="params.transferTime"
  22. @input="params.transferTime = params.transferTime.replace(/\D/g, '')" />
  23. </div>
  24. </div>
  25. <span style="font-size: 12px;font-weight: 400;color: #3B7FFF;line-height: 16px;margin-top: 5px;"
  26. @click="params.transferTime && serviceCount()" :class="{ opacity: !params.transferTime }">{{ countLoading ? '正在计算中...' : '服务费计算'
  27. }}</span>
  28. <div class="transfer-tip">
  29. <div>
  30. 温馨提示:
  31. </div>
  32. <div class="transfer-tip-content">
  33. <div v-html="html"></div>
  34. </div>
  35. </div>
  36. <div class="transfer-btn">
  37. <van-button type="info" block
  38. :disabled="!params.transferUserCardId || !params.acceptUserCardId || !params.transferTime"
  39. :loading="allocateLoading" @click="changePopUpType(0)" loading-text="正在分配时间中...">
  40. 分配时间
  41. </van-button>
  42. </div>
  43. <van-dialog v-model="visible" :title="clickType ? '服务费计算' : ''" confirmButtonColor="#3B7FFF" className="dialog"
  44. showCancelButton cancelButtonColor="#999999" @confirm="!clickType && confirm()"
  45. @close="allocateLoading = false">
  46. <div style="padding: 16px;font-weight: 100;">
  47. <template v-if="clickType">
  48. <div style="display: flex; justify-content: space-between;">
  49. <div>转移天数:</div>
  50. <div style="color: #F9F9F9;">{{ params.transferTime }}天</div>
  51. </div>
  52. <div style="display: flex; justify-content: space-between;">
  53. <div>服务费:</div>
  54. <div style="color: #F9F9F9;">{{ serviceCharge }}天</div>
  55. </div>
  56. </template>
  57. <template v-else>
  58. <div style="line-height: 30px;">
  59. <div style="text-align: center;font-weight:bold;">
  60. 确定要将【{{ transferUserCardName }}】
  61. </div>
  62. <div style="text-align: center;">
  63. 时间分配给【{{ acceptUserCardName }}】
  64. </div>
  65. <div style="text-align: center;margin-top: 10px">
  66. 服务费:{{ serviceCharge }}天
  67. </div>
  68. </div>
  69. </template>
  70. </div>
  71. </van-dialog>
  72. </div>
  73. </template>
  74. <script>
  75. import {
  76. sha256
  77. } from 'js-sha256';
  78. import BigNumber from "bignumber.js";
  79. import { Toast } from 'vant'
  80. const comoros = () => import('./comoros.vue')
  81. export default {
  82. name: 'tansferDuration',
  83. components: {
  84. comoros
  85. },
  86. props: {
  87. token: {
  88. type: String,
  89. default: ''
  90. }
  91. },
  92. data() {
  93. return {
  94. visible: false,// 显示弹窗
  95. transferPhoneList: [], // 云机列表
  96. buyVipType: '', // 当前选中的云机类型
  97. params: {},
  98. acceptUserCardKey: +new Date(),
  99. transferUserCardKey: +new Date(),
  100. acceptUserCardName: '',
  101. transferUserCardName: '',
  102. // 点击类型 0 是确认转移、1是计算手续费
  103. clickType: 0,
  104. // 计算loading
  105. countLoading: false,
  106. // 计算服务费的对象
  107. countObj: {},
  108. // 服务费
  109. serviceCharge: '',
  110. // 分配时间loading
  111. allocateLoading: false,
  112. html: ''
  113. };
  114. },
  115. mounted() {
  116. this.init()
  117. this.getFeeRatio()
  118. this.getRule()
  119. },
  120. methods: {
  121. init() {
  122. this.params = {
  123. acceptUserCardId: '', // 接受设备ID
  124. transferUserCardId: '', // 转移设备ID
  125. transferTime: '' // 转移天数
  126. }
  127. this.acceptUserCardKey = +new Date()
  128. this.transferUserCardKey = +new Date()
  129. this.buyVipType = ''
  130. this.serviceCharge = ''
  131. this.getTransferPhoneList()
  132. },
  133. // 获取云机列表
  134. getTransferPhoneList() {
  135. this.$axios.$get('resources/v5/time/transfer/getTransferPhoneList', { header: { token: this.token } }).then(res => {
  136. if (res.success) {
  137. this.transferPhoneList = res.data
  138. }
  139. })
  140. },
  141. // 确认框
  142. comorosConfirm() {
  143. this.acceptUserCardKey = +new Date()
  144. this.params.acceptUserCardId = ''
  145. },
  146. // 获取手续费比例
  147. getFeeRatio() {
  148. this.$axios.$get('resources/v5/time/transfer/getFeeRatio', { headers: { Authorization: this.token } }).then(res => {
  149. if (res.success) {
  150. res.data.transferMinDay = res.data.transferMinDay * 24 * 60
  151. this.countObj = res.data
  152. }
  153. })
  154. },
  155. // 确定提交
  156. async confirm() {
  157. // 获取服务器时间
  158. let requestTime = await this.$axios.$get('pay/v1/order/getSystemTime', { headers: { Authorization: this.token } })
  159. requestTime = new Date(requestTime.data * 1000).$formatTime()
  160. const requestTimeSign = sha256("Register_SZX_2023:" + requestTime)
  161. this.$axios.$post('resources/v5/time/transfer/transferDurationOperation', {
  162. ...this.params,
  163. requestTime
  164. }, { headers: { Authorization: this.token, requestTimeSign } }).then(res => {
  165. if (res.success) {
  166. this.init()
  167. Toast.success(res.msg)
  168. }
  169. }).catch(err => {
  170. Toast.fail(err.message)
  171. }).finally(() => {
  172. this.allocateLoading = false
  173. })
  174. },
  175. // 服务费计算
  176. serviceCount(bool = true) {
  177. if (this.countLoading) return
  178. if (bool) this.countLoading = true
  179. const arr = this.countObj.list.sort((a, b) => {
  180. console.log(a, b)
  181. return a.timeConsumingEnd - b.timeConsumingEnd
  182. })
  183. console.log(arr)
  184. let commission = null
  185. for (const i of arr) {
  186. if (this.params.transferTime <= i.timeConsumingEnd) {
  187. commission = i.commission
  188. break
  189. }
  190. }
  191. if (!commission) commission = this.countObj.commissionSet
  192. this.serviceCharge = +new BigNumber(this.params.transferTime).times(new BigNumber(commission).div(100))
  193. this.countLoading = false
  194. if (bool) this.changePopUpType(1)
  195. },
  196. changePopUpType(e) {
  197. if (!e) {
  198. this.serviceCount(false)
  199. this.allocateLoading = true
  200. }
  201. this.visible = true
  202. this.clickType = e
  203. },
  204. // 获取规则
  205. getRule() {
  206. this.$axios.$get('/public/v4/agreement/content', {
  207. params: {
  208. agreementCoding: 'YJSBSJZY2024'
  209. }, headers: { Authorization: this.token }
  210. }).then(res => {
  211. const html = res.data.content;
  212. const rx = /<body[^>]*>([\s\S]+?)<\/body>/i;
  213. let m = rx.exec(html);
  214. if (m) {
  215. m = m[1]
  216. };
  217. console.log(m)
  218. this.html = m
  219. })
  220. }
  221. },
  222. };
  223. </script>
  224. <style lang="scss" scoped>
  225. .transfer {
  226. padding: 0 16px 90px;
  227. .transfer-item {
  228. margin-top: 16px;
  229. }
  230. .transfer-tip {
  231. margin-top: 24px;
  232. }
  233. .transfer-item-input {
  234. margin-top: 8px;
  235. display: flex;
  236. align-items: center;
  237. }
  238. .transfer-tip-content {
  239. margin-top: 8px;
  240. }
  241. .transfer-tip-content {
  242. font-size: 12px;
  243. font-family: PingFangSC, PingFang SC;
  244. font-weight: 400;
  245. color: #959799;
  246. line-height: 17px;
  247. }
  248. .transfer-btn {
  249. width: calc(100% - 32px);
  250. position: fixed;
  251. left: 16px;
  252. bottom: 36px;
  253. height: 48px;
  254. .van-button {
  255. height: 100%;
  256. border-radius: 5px;
  257. }
  258. }
  259. .van-field {
  260. background: #2C2C2D;
  261. margin-right: 12px;
  262. border-radius: 5px;
  263. height: 52px !important;
  264. font-weight: 500 !important;
  265. align-items: center;
  266. ::v-deep .van-field__control {
  267. color: #fff;
  268. }
  269. ::v-deep .van-field__control::-webkit-input-placeholder {
  270. color: #999999 !important;
  271. }
  272. }
  273. }
  274. .dialog {
  275. color: #CFD1D4;
  276. ::v-deep [class*=van-hairline]::after {
  277. border-color: rgba(72, 72, 72, 0.5);
  278. }
  279. &,
  280. ::v-deep .van-button__content {
  281. background: #2C2C2D;
  282. }
  283. }
  284. .opacity {
  285. opacity: .4;
  286. }
  287. .transfer-tip-content {
  288. ::v-deep ol {
  289. list-style-type: decimal;
  290. }
  291. ::v-deep ul {
  292. list-style-type: disc;
  293. }
  294. }
  295. </style>