years.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <template>
  2. <div class="flex flex-center flex-col">
  3. <div class="full-width">
  4. <basic-tab
  5. :tabs="tabs"
  6. :full="true"
  7. @change="change"
  8. style="width: 99%"
  9. />
  10. </div>
  11. <el-row class="flex flex-center full-width mt-10 flex-wrap">
  12. <el-col :lg="12" :xl="6" v-for="i in dash" :key="i">
  13. <div class="box" :style="`box-shadow: ` + i.box">
  14. <div class="flex flex-col bold font-16 padding-14">
  15. <div class="flex flex-justify-start flex-align-end">
  16. <img :src="i.icon" />
  17. <span class="grey-6 ml-5">{{ i.name }}</span>
  18. <span v-if="i.index !== 2" class="font-12 grey-6 ml-10"
  19. >万元</span
  20. >
  21. </div>
  22. <div
  23. v-if="i.index !== 2"
  24. class="flex flex-align-end flex-justify-start mt-10"
  25. >
  26. <span class="grey" style="margin-left: 3px">¥</span>
  27. <span class="ml-5 font-24" :style="`color:` + i.color">{{
  28. info[i.prop] ? info[i.prop].toLocaleString() : '0'
  29. }}</span>
  30. <el-icon
  31. :size="15"
  32. v-if="i.index === 0 && user.info.viewStage === 1"
  33. class="ml-10 pointer"
  34. @click="edit(i)"
  35. >
  36. <Edit />
  37. </el-icon>
  38. </div>
  39. <div v-else class="flex flex-justify-start flex-center full-width">
  40. <div class="progress-bar mt-10">
  41. <div
  42. v-if="info[i.prop]"
  43. class="bar full-height"
  44. :style="
  45. `width: ` +
  46. (Number.parseFloat(info[i.prop].replace('%', '')) > 100
  47. ? '100%'
  48. : info[i.prop])
  49. "
  50. ></div>
  51. </div>
  52. <span class="ml-10 font-24 mt-10" :style="`color:` + i.color">{{
  53. info[i.prop]
  54. }}</span>
  55. </div>
  56. </div>
  57. <div style="margin-top: -20px">
  58. <wave :color="i.color" />
  59. </div>
  60. </div>
  61. </el-col>
  62. </el-row>
  63. </div>
  64. </template>
  65. <script>
  66. import basicTab from '@/components/basic-tab/index.vue'
  67. import wave from '@/views/invest/components/wave.vue'
  68. import { useStore } from '@/store/user.js'
  69. import { ElMessageBox } from 'element-plus'
  70. import index from '@/views/task/Index.vue'
  71. export default {
  72. name: 'years',
  73. computed: {
  74. index() {
  75. return index
  76. }
  77. },
  78. components: { basicTab, wave },
  79. setup() {
  80. const user = useStore()
  81. return { user }
  82. },
  83. props: {
  84. deptId: {
  85. type: String,
  86. default: ''
  87. },
  88. year: {
  89. type: String,
  90. default: ''
  91. }
  92. },
  93. watch: {
  94. deptId: {
  95. handler(val) {
  96. this.load()
  97. },
  98. immediate: true
  99. },
  100. year: {
  101. handler(val) {
  102. this.load()
  103. },
  104. immediate: true
  105. }
  106. },
  107. data() {
  108. return {
  109. times: [],
  110. info: {},
  111. tabs: [
  112. { name: '总览', value: 0 },
  113. { name: '一季度', value: 1 },
  114. { name: '二季度', value: 2 },
  115. { name: '三季度', value: 3 },
  116. { name: '四季度', value: 4 }
  117. ],
  118. quarter: '',
  119. dash: [
  120. {
  121. icon: new URL('../../../assets/svg/invest/1.svg', import.meta.url)
  122. .href,
  123. name: '责任目标',
  124. value: 0,
  125. prop: 'plan_complete_amount',
  126. box: '0 1px 10px 0 rgba(105, 204, 243, 0.3)',
  127. color: '#32B5F3',
  128. index: 0,
  129. background: new URL(
  130. '../../../assets/svg/invest/bg1.svg',
  131. import.meta.url
  132. ).href
  133. },
  134. {
  135. icon: new URL('../../../assets/svg/invest/2.svg', import.meta.url)
  136. .href,
  137. name: '累计完成投资',
  138. value: 0,
  139. prop: 'total_complete_amount',
  140. box: '0 1px 10px 0 rgba(200, 150, 230, 0.3)',
  141. color: '#AD46CB',
  142. index: 1
  143. },
  144. {
  145. icon: new URL('../../../assets/svg/invest/3.svg', import.meta.url)
  146. .href,
  147. name: '投资完成比例',
  148. value: 0,
  149. prop: 'rate',
  150. box: '0 1px 10px 0 rgba(236, 171, 83, 0.3)',
  151. color: '#EC9040',
  152. index: 2
  153. },
  154. {
  155. icon: new URL('../../../assets/svg/invest/4.svg', import.meta.url)
  156. .href,
  157. name: '计划纳统投资',
  158. value: 0,
  159. prop: 'total_investment_amount',
  160. box: '0 1px 10px 0 rgba(119, 94, 241, 0.3)',
  161. color: '#4F5EE7',
  162. index: 3
  163. }
  164. ]
  165. }
  166. },
  167. created() {
  168. this.init()
  169. },
  170. methods: {
  171. load() {
  172. this.tabs[0].name = this.year + '年总览'
  173. this.$api.invest
  174. .homeInvest({
  175. deptId: this.deptId === null ? '' : this.deptId,
  176. year: this.year === null ? '' : this.year,
  177. quarter: this.quarter
  178. })
  179. .then(res => {
  180. if (res.code === 200) {
  181. this.info = res.data
  182. }
  183. })
  184. },
  185. init() {
  186. const year = new Date().getFullYear()
  187. this.tabs[0].name = year + '年总览'
  188. },
  189. change(index) {
  190. this.quarter = index.value === 0 ? '' : index.value
  191. this.$emit('change', index)
  192. this.load()
  193. },
  194. edit(item) {
  195. ElMessageBox.prompt(
  196. '当前责任目标为' +
  197. this.info[item.prop].toLocaleString() +
  198. '万元,请输入新的责任目标(数字,小数点)',
  199. '提示',
  200. {
  201. confirmButtonText: '保存',
  202. cancelButtonText: '取消',
  203. inputPattern: /^([1-9]\d*|0)(\.\d+)?$/,
  204. inputErrorMessage: '信息错误'
  205. }
  206. ).then(({ value }) => {
  207. let data = {}
  208. switch (this.quarter) {
  209. case 0: // 年度
  210. data = { number: value }
  211. break
  212. case 1: // 1季度
  213. data = { number: value, type: 1 }
  214. break
  215. case 2: // 2季度
  216. data = { number: value, type: 2 }
  217. break
  218. case 3: // 3季度
  219. data = { number: value, type: 3 }
  220. break
  221. case 4: // 4季度
  222. data = { number: value, type: 4 }
  223. break
  224. default:
  225. data = { number: value }
  226. break
  227. }
  228. this.$api.invest
  229. .savePlan(
  230. Object.assign(
  231. {
  232. deptId: this.deptId === null ? '' : this.deptId,
  233. year: this.year === null ? '' : this.year
  234. },
  235. data
  236. )
  237. )
  238. .then(res => {
  239. if (res.code === 200) {
  240. this.$message.success(res.msg)
  241. this.info[item.prop] = value
  242. } else {
  243. this.$message.error(res.msg)
  244. }
  245. })
  246. })
  247. }
  248. }
  249. }
  250. </script>
  251. <style lang="scss" scoped>
  252. .content {
  253. background-image: url('./src/assets/svg/invest/wave/1.svg');
  254. background-size: 100% 100%;
  255. background-repeat: no-repeat;
  256. }
  257. .box {
  258. min-width: 280px;
  259. border-radius: 8px;
  260. min-height: 115px;
  261. margin: 20px;
  262. background-color: #f6f9fd;
  263. }
  264. .progress-bar {
  265. width: 60%;
  266. height: 10px;
  267. background: white;
  268. border-radius: 10px;
  269. margin-left: 5px;
  270. border: 1px solid #f8b65f;
  271. }
  272. .bar {
  273. background: #f8b65f;
  274. border-radius: 10px;
  275. }
  276. </style>