Program.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <template>
  2. <div class="l-flex--col c-program">
  3. <div
  4. class="c-program__body u-pointer"
  5. :style="style"
  6. @click="onClick"
  7. >
  8. <el-tooltip
  9. v-if="isRejected"
  10. :content="program.remark"
  11. placement="top-start"
  12. >
  13. <i
  14. class="c-program__warning el-icon-warning-outline"
  15. @click.stop
  16. />
  17. </el-tooltip>
  18. <span class="c-program__ratio">{{ program.resolutionRatio }}</span>
  19. <div class="c-program__time u-ellipsis">{{ time }}</div>
  20. </div>
  21. <div class="l-flex--col c-program__footer">
  22. <edit-input
  23. v-model.trim="name"
  24. class="c-program__name"
  25. :disabled="disabled"
  26. @edit="onEdit"
  27. />
  28. <div class="c-program__buttons l-flex--row">
  29. <slot />
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. import { getAssetUrl } from '@/api/asset'
  36. import { updateProgramName } from '@/api/program'
  37. import { State } from '@/constant'
  38. export default {
  39. name: 'Program',
  40. props: {
  41. program: {
  42. type: Object,
  43. required: true
  44. }
  45. },
  46. data () {
  47. return {
  48. name: this.program.name
  49. }
  50. },
  51. computed: {
  52. disabled () {
  53. return this.program.status !== State.READY
  54. },
  55. style () {
  56. const img = this.program.img
  57. return img
  58. ? {
  59. backgroundSize: 'contain',
  60. backgroundImage: `url("${/^data/.test(img) ? img : getAssetUrl(img)}")`
  61. }
  62. : {}
  63. },
  64. time () {
  65. return this.program.updateTime?.split(' ')[0]
  66. },
  67. isRejected () {
  68. return this.program.status > State.RESOLVED
  69. }
  70. },
  71. methods: {
  72. onClick () {
  73. const { id, status } = this.program
  74. this.$viewProgram(id, status !== State.SUBMITTED && status !== State.RESOLVED ? 'design' : 'view')
  75. },
  76. onEdit () {
  77. const name = this.name
  78. if (!name) {
  79. this.name = this.program.name
  80. return
  81. }
  82. if (name === this.program.name) {
  83. return
  84. }
  85. updateProgramName({
  86. id: this.program.id,
  87. name
  88. }).catch(
  89. () => {
  90. this.name = this.program.name
  91. }
  92. )
  93. }
  94. }
  95. }
  96. </script>
  97. <style lang="scss" scoped>
  98. .c-program {
  99. align-self: flex-start;
  100. margin: 0 2px 8px;
  101. box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.05);
  102. &__body {
  103. position: relative;
  104. padding-top: 56.25%;
  105. color: #fff;
  106. font-size: 16px;
  107. border-radius: $radius $radius 0 0;
  108. background: rgba(0, 0, 0, 0.8) url("~@/assets/program_bg.png") center center /
  109. 100% 100% no-repeat;
  110. }
  111. &__warning {
  112. position: absolute;
  113. top: 0;
  114. left: 0;
  115. padding: 4px 6px;
  116. color: $warning;
  117. font-size: 24px;
  118. }
  119. &__ratio {
  120. position: absolute;
  121. top: 0;
  122. right: 0;
  123. padding: 4px 6px;
  124. font-size: 12px;
  125. background-color: rgba(0, 0, 0, 0.5);
  126. border-radius: 0 $radius 0 $radius;
  127. }
  128. &__time {
  129. position: absolute;
  130. left: 0;
  131. bottom: 0;
  132. width: 100%;
  133. font-size: 14px;
  134. padding: 10px 6px 4px;
  135. background-image: linear-gradient(
  136. to bottom,
  137. rgba(#000, 0) 0%,
  138. rgba(#000, 0.6) 100%
  139. );
  140. }
  141. &__footer {
  142. border-radius: 0 0 $radius $radius;
  143. }
  144. &__name {
  145. color: $black;
  146. font-weight: bold;
  147. }
  148. &__buttons {
  149. border-top: 1px solid $border;
  150. &:empty {
  151. display: none;
  152. }
  153. & > div {
  154. flex: 1 0 0;
  155. padding: 12px 10px;
  156. color: $blue;
  157. font-size: 14px;
  158. font-weight: bold;
  159. line-height: 1;
  160. text-align: center;
  161. cursor: pointer;
  162. &:hover {
  163. background-color: $blue--light;
  164. }
  165. }
  166. }
  167. }
  168. </style>