You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
6.0 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <script lang="ts" setup>
  2. import { ElMessageBox } from 'element-plus'
  3. import { FtMessage } from 'libs/message'
  4. import { computed, ref } from 'vue'
  5. import { useRouter } from 'vue-router'
  6. import { updateContainer } from '@/apis/container'
  7. import { useSolutionStore } from '@/stores/useSolutionStore'
  8. const props = defineProps({
  9. itemIndex: {
  10. type: Number,
  11. required: true,
  12. },
  13. solutionItem: {
  14. type: Object,
  15. default: () => {},
  16. },
  17. })
  18. const emits = defineEmits<{
  19. (e: 'ok'): void
  20. }>()
  21. const router = useRouter()
  22. const visible = ref(false)
  23. const solutionStore = useSolutionStore()
  24. const solutionId = ref()
  25. const selectedSolutionItem = ref()
  26. const solutionInfo = ref(props.solutionItem)
  27. const solutionStyle = computed(() => {
  28. const difference = (solutionInfo.value.capacityTotal - solutionInfo.value.capacityUsed) / solutionInfo.value.capacityTotal
  29. const process = 100 - (difference * 100)
  30. const filter = difference > 0.4 ? 'hue-rotate(270deg) saturate(100) brightness(81%)' : difference > 0.1 ? 'hue-rotate(150deg) saturate(100)' : 'hue-rotate(120deg) saturate(100)'
  31. return {
  32. 'filter': filter,
  33. '-webkit-mask': `linear-gradient(to bottom, transparent ${process}%, #EEEFF8 ${process + 0.1}%)`,
  34. }
  35. })
  36. const onInputBlur = async () => {
  37. if (solutionInfo.value.capacityUsed > solutionInfo.value.capacityTotal) {
  38. FtMessage.error(`容器容量不能超过${solutionInfo.value.capacityTotal}mL`)
  39. solutionInfo.value.capacityUsed = 5000
  40. return
  41. }
  42. await ElMessageBox.confirm(
  43. '确认保存吗? ',
  44. '提示',
  45. {
  46. confirmButtonText: '确认',
  47. showClose: false,
  48. showCancelButton: true,
  49. closeOnClickModal: false,
  50. closeOnPressEscape: false,
  51. type: 'warning',
  52. },
  53. )
  54. await saveContainer()
  55. }
  56. const saveContainer = async () => {
  57. if (!solutionInfo.value.capacityUsed) {
  58. FtMessage.warning('请输入当前容量')
  59. return
  60. }
  61. if (!solutionInfo.value.solutionId) {
  62. FtMessage.warning('请选择酸液')
  63. return
  64. }
  65. const params: Container.ContainerItem = {
  66. id: solutionInfo.value.id,
  67. type: 0,
  68. solutionId: solutionInfo.value.solutionId,
  69. pumpId: solutionInfo.value.pumpId,
  70. capacityTotal: solutionInfo.value.capacityTotal,
  71. capacityUsed: solutionInfo.value.capacityUsed,
  72. filled: solutionInfo.value.filled,
  73. }
  74. await updateContainer(params)
  75. FtMessage.success('保存成功')
  76. emits('ok')
  77. }
  78. const onSolutionChange = (value: number) => {
  79. if (value) {
  80. solutionId.value = value
  81. solutionInfo.value.solutionId = value
  82. selectedSolutionItem.value = solutionStore.solutionList.filter(item => item.id === value)[0]
  83. }
  84. }
  85. const onClose = () => {
  86. solutionId.value = null
  87. visible.value = false
  88. }
  89. const onSubmitSolution = () => {
  90. if (!solutionStore.solutionList.length) {
  91. // 跳转至配置酸液页面
  92. router.push('/solution')
  93. return
  94. }
  95. solutionInfo.value.solutionName = selectedSolutionItem.value.name
  96. solutionInfo.value.solutionId = selectedSolutionItem.value.id
  97. saveContainer()
  98. onClose()
  99. }
  100. </script>
  101. <template>
  102. <div class="liquied-item">
  103. <div class="header">
  104. <div class="solution-select">
  105. <div class="solution-name">
  106. <span v-if="solutionInfo.solutionName">{{ solutionInfo.solutionName }}</span>
  107. <span v-else style="color:#d2d2d2">选择酸液</span>
  108. </div>
  109. </div>
  110. </div>
  111. <div class="content">
  112. <div class="bottle_base">
  113. <img class="content-img" src="@/assets/images/liquied/liquied_bottle.svg" alt="chemical-bottle">
  114. </div>
  115. <div class="bottle" :style="solutionStyle">
  116. <img class="content-img" src="@/assets/images/liquied/liquied_bottle.svg" alt="chemical-bottle">
  117. </div>
  118. </div>
  119. <div class="footer">
  120. <div class="footer-content">
  121. <span>{{ solutionInfo.capacityTotal }}mL</span>
  122. </div>
  123. <div class="footer-edit">
  124. <span>已使用</span>
  125. <el-input v-model="solutionInfo.capacityUsed" type="number" @blur="onInputBlur">
  126. <template #append>
  127. mL
  128. </template>
  129. </el-input>
  130. </div>
  131. </div>
  132. <FtDialog v-model="visible" title="选择酸液" :ok-handle="onSubmitSolution" @cancel="onClose">
  133. <div v-if="solutionStore.solutionList.length">
  134. <el-radio-group v-model="solutionId" size="large" class="radio-group" @change="onSolutionChange">
  135. <el-radio-button v-for="item in solutionStore.solutionList" :key="item.id" :label="item.name" :value="item.id" class="radio-marge" />
  136. </el-radio-group>
  137. </div>
  138. <div v-else>
  139. <el-empty description="description">
  140. <template #description>
  141. 未添加酸液请在溶液管理中配置
  142. </template>
  143. </el-empty>
  144. </div>
  145. </FtDialog>
  146. </div>
  147. </template>
  148. <style scoped>
  149. .liquied-item {
  150. border: 1px solid #ccc;
  151. border-radius: 10px;
  152. width: 200px;
  153. height: 300px;
  154. text-align: center;
  155. display: flex;
  156. flex-direction: column;
  157. align-items: center;
  158. justify-content: space-between;
  159. }
  160. .content{
  161. position: relative;
  162. display: flex;
  163. justify-content: center;
  164. }
  165. .bottle_base{
  166. position: relative;
  167. }
  168. .bottle {
  169. position: absolute;
  170. }
  171. .header {
  172. display: flex;
  173. align-items: center;
  174. background: rgba(25, 137, 250, 0.1216);
  175. justify-content: center;
  176. border-radius: 10px 10px 0 0;
  177. padding:10px;
  178. width: 100%;
  179. }
  180. .content-img{
  181. height: 150px;
  182. margin: 10px;
  183. }
  184. .footer-content{
  185. display: flex;
  186. justify-content: center;
  187. }
  188. .footer-edit {
  189. display: flex;
  190. justify-content: space-around;
  191. align-items: center;
  192. padding: 10px 0;
  193. .el-input {
  194. margin-left: 10px;
  195. width: 120px;
  196. }
  197. }
  198. .checked {
  199. text-decoration: line-through;
  200. }
  201. .solution-select{
  202. display:flex;
  203. width: 120px;
  204. height: 25px;
  205. text-align: center;
  206. margin-left: 5px;
  207. align-items: center;
  208. border-radius: 5px;
  209. }
  210. .solution-name{
  211. width: 100px;
  212. height: 25px;
  213. display: flex;
  214. align-items: center;
  215. justify-content: center;
  216. }
  217. .add-icon{
  218. margin-right: -4px;
  219. }
  220. .button-icon{
  221. height: 25px;
  222. width: 25px;
  223. margin: 3px;
  224. }
  225. .radio-marge{
  226. margin: 10px;
  227. border: 1px solid #e0e0e0;
  228. }
  229. </style>