work-order-materials.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <template>
  2. <scroll-view scroll-y="true" class="work-order-materials">
  3. <view class="device-section" v-for="(material, index) in materialsData">
  4. <!-- 保养项 -->
  5. <view class="item-module">
  6. <view class="item-content flex-row align-center justify-between">
  7. <view class="item-title">
  8. <span class="item-title-width"
  9. >{{ $t("maintenanceWorkOrder.maintenanceItems") }}:</span
  10. >
  11. </view>
  12. <view class="item-title">
  13. <span>{{ material.bomName }}</span>
  14. </view>
  15. </view>
  16. <view class="module-border"> </view>
  17. </view>
  18. <!-- 物料名称 -->
  19. <view class="item-content flex-row align-center justify-between">
  20. <view class="item-title">
  21. <span class="item-title-width"
  22. >{{ $t("workOrder.materialName") }}:</span
  23. >
  24. </view>
  25. <view class="item-title">
  26. <!-- 新增物料时,需要填写 -->
  27. <uni-easyinput
  28. v-if="material.isNew"
  29. type="text"
  30. style="text-align: right"
  31. :styles="{ disableColor: 'transparent' }"
  32. :inputBorder="false"
  33. :clearable="true"
  34. :disabled="materialDisabled || material.isNotConsumeMaterial || material.isStatusClosed"
  35. :placeholder="placeholderRequired"
  36. v-model="material.materialName"
  37. />
  38. <span v-else>{{ material.materialName }}</span>
  39. </view>
  40. </view>
  41. <!-- 物料编码 -->
  42. <view class="item-content flex-row align-center justify-between">
  43. <view class="item-title">
  44. <span class="item-title-width"
  45. >{{ $t("workOrder.materialCode") }}:</span
  46. >
  47. </view>
  48. <view class="item-title">
  49. <!-- 新增物料时,需要填写 -->
  50. <uni-easyinput
  51. v-if="material.isNew"
  52. type="text"
  53. style="text-align: right"
  54. :styles="{ disableColor: 'transparent' }"
  55. :inputBorder="false"
  56. :clearable="true"
  57. :disabled="
  58. materialDisabled ||
  59. material.isNotConsumeMaterial ||
  60. material.isStatusClosed
  61. "
  62. :placeholder="placeholderFill"
  63. v-model="material.materialCode"
  64. />
  65. <span v-else>{{ material.materialCode }}</span>
  66. </view>
  67. </view>
  68. <!-- 单位 -->
  69. <view class="item-content flex-row align-center justify-between">
  70. <view class="item-title">
  71. <span class="item-title-width"> {{ $t("workOrder.unit") }}: </span>
  72. </view>
  73. <view class="item-title">
  74. <!-- 新增物料时,需要填写 -->
  75. <uni-easyinput
  76. v-if="material.isNew"
  77. type="text"
  78. style="text-align: right"
  79. :styles="{ disableColor: 'transparent' }"
  80. :inputBorder="false"
  81. :clearable="true"
  82. :disabled="
  83. materialDisabled ||
  84. material.isNotConsumeMaterial ||
  85. material.isStatusClosed
  86. "
  87. :placeholder="placeholderFill"
  88. v-model="material.unit"
  89. />
  90. <span v-else>{{ material.unit }}</span>
  91. </view>
  92. </view>
  93. <!-- 单价 -->
  94. <view class="item-content flex-row align-center justify-between">
  95. <view class="item-title">
  96. <span class="item-title-width">
  97. {{ $t("workOrder.unitPriceCNY") }}:
  98. </span>
  99. </view>
  100. <view class="item-title">
  101. <uni-easyinput
  102. type="digit"
  103. style="text-align: right"
  104. :styles="{ disableColor: 'transparent' }"
  105. :inputBorder="false"
  106. :clearable="true"
  107. :disabled="
  108. materialDisabled ||
  109. material.isNotConsumeMaterial ||
  110. material.isStatusClosed
  111. "
  112. :placeholder="placeholderRequired"
  113. @change="onMaterialChange"
  114. v-model="material.unitPrice"
  115. />
  116. </view>
  117. </view>
  118. <!-- 消耗数量 -->
  119. <view class="item-content flex-row align-center justify-between">
  120. <view class="item-title">
  121. <span class="item-title-width">
  122. {{ $t("workOrder.consumptionQuantity") }}:
  123. </span>
  124. </view>
  125. <uni-easyinput
  126. type="digit"
  127. style="text-align: right"
  128. :styles="{ disableColor: 'transparent' }"
  129. :inputBorder="false"
  130. :clearable="true"
  131. :disabled="
  132. materialDisabled ||
  133. material.isNotConsumeMaterial ||
  134. material.isStatusClosed
  135. "
  136. :placeholder="placeholderRequired"
  137. @change="onMaterialChange"
  138. v-model="material.quantity"
  139. />
  140. </view>
  141. <!-- 库存数量 -->
  142. <view
  143. class="item-content flex-row align-center justify-between"
  144. v-if="!material.isNew"
  145. >
  146. <view class="item-title">
  147. <span class="item-title-width">
  148. {{ $t("workOrder.inventoryQuantity") }}:
  149. </span>
  150. </view>
  151. <view class="item-title">
  152. <span>{{ material.stockQuantity }}</span>
  153. </view>
  154. </view>
  155. <!-- 来源 -->
  156. <view class="item-content flex-row align-center justify-between">
  157. <view class="item-title">
  158. <span class="item-title-width"> {{ $t("workOrder.source") }}: </span>
  159. </view>
  160. <view class="item-title">
  161. <span>{{ material.materialSource }}</span>
  162. </view>
  163. </view>
  164. <!-- 操作按钮 -->
  165. <view class="item-opera flex-row justify-end">
  166. <!-- 删除按钮 -->
  167. <button
  168. type="primary"
  169. :plain="true"
  170. @click="ondelete(material, index)"
  171. v-if="
  172. !materialDisabled &&
  173. !material.isNotConsumeMaterial &&
  174. !material.isStatusClosed
  175. "
  176. >
  177. {{ $t("operation.delete") }}
  178. </button>
  179. </view>
  180. </view>
  181. </scroll-view>
  182. <!-- 提示信息弹窗 -->
  183. <uni-popup ref="alertDialogRef" type="dialog">
  184. <!-- 删除提示 -->
  185. <uni-popup-dialog
  186. :type="'warn'"
  187. :title="$t('api.message')"
  188. :cancelText="$t('operation.cancel')"
  189. :confirmText="$t('operation.confirm')"
  190. :content="`${$t('workOrder.isDeleteMaterial')}?`"
  191. @confirm="dialogConfirm"
  192. @close="dialogClose"
  193. ></uni-popup-dialog>
  194. </uni-popup>
  195. </template>
  196. <script setup>
  197. import { onLoad, onReady, onBackPress } from "@dcloudio/uni-app";
  198. import { ref, reactive, computed, getCurrentInstance, watch } from "vue";
  199. import dayjs from "dayjs";
  200. // --------------------------引用组件--------------------------------------
  201. // --------------------------引用全局变量$t---------------------------------
  202. const { appContext } = getCurrentInstance();
  203. const t = appContext.config.globalProperties.$t;
  204. // --------------------------接收参数---------------------------------------
  205. const props = defineProps({
  206. // 保养项列表
  207. materialsData: {
  208. type: Array,
  209. default: () => [],
  210. },
  211. materialDisabled: {
  212. type: Boolean,
  213. default: false,
  214. },
  215. });
  216. console.log("🚀 ~ props.materialsData:", props.materialsData);
  217. // 根据materialDisabled动态返回表单placeholder - 填写或禁用
  218. const placeholderFill = computed(() => {
  219. return props.materialDisabled ? "" : t("operation.PleaseFillIn");
  220. });
  221. const placeholderRequired = computed(() => {
  222. return props.materialDisabled
  223. ? ""
  224. : t("operation.PleaseFillIn") + t("workOrder.materialRequired");
  225. });
  226. // 监听物料数量变化
  227. watch(
  228. () => props.materialsData,
  229. (newVal) => {
  230. console.log("🚀 ~ props.materialsData:materialChanged", newVal);
  231. emit("materialChanged");
  232. },
  233. { deep: true }
  234. );
  235. // 提示信息弹窗
  236. const alertDialogRef = ref(null);
  237. // 待删除的物料
  238. const materialToDelete = ref({});
  239. // 删除物料
  240. const ondelete = (material, index) => {
  241. // 记录待删除的物料
  242. materialToDelete.value.material = material;
  243. materialToDelete.value.index = index;
  244. // 显示删除提示弹窗
  245. alertDialogRef.value.open();
  246. };
  247. // 删除弹窗确认事件
  248. const dialogConfirm = () => {
  249. console.log("🚀 删除弹窗确认事件:");
  250. emit("deleteMaterial", materialToDelete.value);
  251. // 关闭弹窗
  252. dialogClose();
  253. };
  254. // 删除弹窗关闭事件
  255. const dialogClose = () => {
  256. console.log("🚀 删除弹窗关闭事件:");
  257. // 关闭弹窗
  258. alertDialogRef.value.close();
  259. };
  260. const onMaterialChange = () => {
  261. emit("materialChange");
  262. };
  263. // -------------------------- 暴露给父组件的外部方法 --------------------------
  264. defineExpose({});
  265. // -------------------------- 事件派发 ---------------------------------------
  266. const emit = defineEmits(["deleteMaterial", "materialChanged"]);
  267. </script>
  268. <style lang="scss" scoped>
  269. @import "@/style/work-order-detail.scss";
  270. .work-order-materials {
  271. height: 100%;
  272. }
  273. </style>