outputInfo.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <template>
  2. <up-popup :show="show" mode="bottom" @close="handleClose" :round="20" closeable>
  3. <view class="d-flex flex-cln" style="max-height: 70vh">
  4. <view class="f-s-34 f-w-5 pd-24 pb-16">{{ getTitle() }}</view>
  5. <scroll-view scroll-y class="flex1" style="max-height: 70vh">
  6. <view class="pd-24">
  7. <up-form ref="formRef" :model="formData" :rules="rules" labelPosition="top" labelWidth="auto">
  8. <template v-if="+type == 1">
  9. <!-- 规格等级 -->
  10. <up-form-item label="规格等级" required prop="specnLevel">
  11. <view class="flex1" @click="goToSpecLevel">
  12. <up-input readonly v-model="formData.specnLevel" type="number" placeholder="请选择规格等级" style="padding-left: 0; padding-right: 0" border="bottom" clearable suffixIcon="arrow-down-fill" suffixIconStyle="color: #2A6D52;font-size: 22rpx"> </up-input>
  13. </view>
  14. <view class="ml-20">
  15. <up-checkbox :customStyle="{ marginBottom: '8px' }" label="统货" name="agree" usedAlone :checked="formData.specnLevel == '统货'" @change="handleSpecnLevelChange"> </up-checkbox>
  16. </view>
  17. </up-form-item>
  18. <!-- 产量 -->
  19. <up-form-item label="产量" prop="capacity" required>
  20. <view class="flex1 d-flex">
  21. <view class="flex1 ov-hd" id="capacitypppp">
  22. <up-form-item border-bottom prop="capacity" class="form-item-top-padding-0">
  23. <up-input v-model="formData.capacity" type="number" placeholder="请输入产量" border="none" clearable></up-input>
  24. </up-form-item>
  25. </view>
  26. <view class="pd-5"></view>
  27. <view class="min-w-100">
  28. <ut-action-sheet v-model="formData.unit" :tabs="pt_out_put_unit" title="选择单位">
  29. <up-form-item border-bottom prop="unit" class="form-item-top-padding-0">
  30. <view class="flex1" style="line-height: 24px">
  31. <view v-if="formData?.unit" class="f-s-30 c-#333 f-w-5 flex1">{{ formData?.unit }}</view>
  32. <view v-else class="f-s-30 c-ccc f-w-4 flex1">单位</view>
  33. </view>
  34. <template #right>
  35. <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
  36. </template>
  37. </up-form-item>
  38. </ut-action-sheet>
  39. </view>
  40. </view>
  41. </up-form-item>
  42. <!-- 产出物图片 -->
  43. <up-form-item borderBottom label="产出物图片">
  44. <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image" width="210rpx" height="210rpx" style="card"></ut-upload>
  45. </up-form-item>
  46. <!-- 检验报告 -->
  47. <up-form-item borderBottom label="加工检验报告">
  48. <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array" accept="image,file" width="210rpx" height="210rpx" style="card"></ut-upload>
  49. </up-form-item>
  50. </template>
  51. <!-- 类型 2 特有字段 -->
  52. <template v-else>
  53. <!-- 规格等级 -->
  54. <up-form-item label="规格等级" required prop="specnLevel">
  55. <view class="flex1" @click="goToSpecLevel">
  56. <up-input readonly v-model="formData.specnLevel" type="number" placeholder="请选择规格等级" style="padding-left: 0; padding-right: 0" border="bottom" clearable suffixIcon="arrow-down-fill" suffixIconStyle="color: #2A6D52;font-size: 22rpx"> </up-input>
  57. </view>
  58. <view class="ml-20">
  59. <up-checkbox :customStyle="{ marginBottom: '8px' }" label="统货" name="agree" usedAlone :checked="formData.specnLevel == '统货'" @change="handleSpecnLevelChange"> </up-checkbox>
  60. </view>
  61. </up-form-item>
  62. <!-- 产量 -->
  63. <up-form-item label="产量" prop="capacity" required>
  64. <view class="flex1 d-flex">
  65. <view class="flex1 ov-hd" id="capacitypppp">
  66. <up-form-item border-bottom prop="capacity" class="form-item-top-padding-0">
  67. <up-input v-model="formData.capacity" type="number" placeholder="请输入产量" border="none" clearable></up-input>
  68. </up-form-item>
  69. </view>
  70. <view class="pd-5"></view>
  71. <view class="min-w-100">
  72. <ut-action-sheet v-model="formData.unit" :tabs="pt_out_put_unit" title="选择单位">
  73. <up-form-item border-bottom prop="unit" class="form-item-top-padding-0">
  74. <view class="flex1" style="line-height: 24px">
  75. <view v-if="formData?.unit" class="f-s-30 c-#333 f-w-5 flex1">{{ formData?.unit }}</view>
  76. <view v-else class="f-s-30 c-ccc f-w-4 flex1">单位</view>
  77. </view>
  78. <template #right>
  79. <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
  80. </template>
  81. </up-form-item>
  82. </ut-action-sheet>
  83. </view>
  84. </view>
  85. </up-form-item>
  86. <!-- 切制形态 -->
  87. <ut-action-sheet v-model="formData.finalFormType" :tabs="pt_final_form_type" title="选择切制形态">
  88. <up-form-item borderBottom label="切制形态" prop="finalFormType" required>
  89. <view v-if="formData?.finalFormType" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_final_form_type, formData?.finalFormType) }}</view>
  90. <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择切制形态</view>
  91. <template #right>
  92. <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
  93. </template>
  94. </up-form-item>
  95. </ut-action-sheet>
  96. <!-- 具体切制形态 -->
  97. <up-form-item borderBottom label="具体切制形态" prop="finalFormOther" required>
  98. <up-input v-model="formData.finalFormOther" placeholder="请输入具体切制形态" border="none" clearable></up-input>
  99. </up-form-item>
  100. <!-- 切制尺寸 -->
  101. <up-form-item label="切制尺寸" required>
  102. <view class="flex1 d-flex">
  103. <view class="flex1 ov-hd" id="finalSpecnpppp">
  104. <up-form-item border-bottom prop="finalSpecn" class="form-item-top-padding-0">
  105. <up-input v-model="formData.finalSpecn" type="number" placeholder="请输入切制尺寸" border="none" clearable></up-input>
  106. </up-form-item>
  107. </view>
  108. <view class="pd-5"></view>
  109. <view class="min-w-100">
  110. <ut-action-sheet v-model="formData.finalUnit" :tabs="pt_final_unit" title="选择切制单位">
  111. <up-form-item border-bottom prop="finalUnit" class="form-item-top-padding-0">
  112. <view class="flex1" style="line-height: 24px">
  113. <view v-if="formData?.finalUnit" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_final_unit, formData?.finalUnit) }}</view>
  114. <view v-else class="f-s-30 c-ccc f-w-4 flex1">单位</view>
  115. </view>
  116. <template #right>
  117. <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
  118. </template>
  119. </up-form-item>
  120. </ut-action-sheet>
  121. </view>
  122. </view>
  123. </up-form-item>
  124. <!-- 产出物图片 -->
  125. <up-form-item borderBottom label="产出物图片">
  126. <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image" width="210rpx" height="210rpx" style="card"></ut-upload>
  127. </up-form-item>
  128. <!-- 检验报告 -->
  129. <up-form-item borderBottom label="加工检验报告">
  130. <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array" accept="image,file" width="210rpx" height="210rpx" style="card"></ut-upload>
  131. </up-form-item>
  132. </template>
  133. </up-form>
  134. </view>
  135. <!-- 底部按钮 -->
  136. <view class="d-flex gap-20 pd-24">
  137. <up-button plain type="info" @click="handleClose">取消</up-button>
  138. <up-button type="primary" @click="handleSubmit">确认</up-button>
  139. </view>
  140. </scroll-view>
  141. </view>
  142. </up-popup>
  143. </template>
  144. <script setup lang="ts">
  145. import { useClientRequest } from '@/utils/request';
  146. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  147. const { pt_final_form_type, pt_final_unit, pt_out_put_unit } = toRefs<any>(proxy?.useDict('pt_final_form_type', 'pt_final_unit', 'pt_out_put_unit'));
  148. const props = defineProps<{
  149. show: boolean;
  150. type: number; // 1: 初加工,2: 趁鲜切制
  151. processId: string | number; // 加工任务 ID
  152. isEdit: boolean; // 是否编辑模式
  153. editData: any; // 要编辑的数据
  154. }>();
  155. const emit = defineEmits<{
  156. 'update:show': [value: boolean];
  157. confirm: [data: any];
  158. }>();
  159. const formRef = ref();
  160. // 表单数据
  161. const formData = ref({
  162. specnLevel: '',
  163. capacity: '',
  164. unit: '',
  165. imgs: [] as any[],
  166. examinReport: [] as any[],
  167. finalFormType: '',
  168. finalFormOther: '',
  169. finalSpecn: '',
  170. finalUnit: '',
  171. id: '', // 编辑模式需要 id
  172. });
  173. // 监听 editData 变化,初始化表单数据
  174. watch(
  175. () => props.editData,
  176. (newVal) => {
  177. if (newVal && props.isEdit) {
  178. formData.value = {
  179. specnLevel: newVal?.specnLevel || '',
  180. capacity: newVal?.capacity || '',
  181. unit: newVal?.unit || '',
  182. imgs: newVal?.imgs ? newVal.imgs.split(',').map((url: string) => ({ url })) : [],
  183. examinReport: newVal?.examinReport || [],
  184. finalFormType: newVal?.finalFormType || '',
  185. finalFormOther: newVal?.finalFormOther || '',
  186. finalSpecn: newVal?.finalSpecn || '',
  187. finalUnit: newVal?.finalUnit || '',
  188. id: newVal?.id || '',
  189. };
  190. }
  191. },
  192. { immediate: true },
  193. );
  194. // 动态生成校验规则
  195. const getRules = () => {
  196. const baseRules = {
  197. specnLevel: [{ required: true, message: '请选择规格等级', trigger: 'change' }],
  198. capacity: [
  199. { required: true, message: '请输入产量', trigger: 'blur' },
  200. { type: 'number', message: '产量必须为数字', trigger: 'blur' },
  201. ],
  202. unit: [{ required: true, message: '请选择单位', trigger: 'change' }],
  203. };
  204. if (type.value === 2) {
  205. // 类型 2(趁鲜切制)所有字段必填
  206. return {
  207. ...baseRules,
  208. finalFormType: [{ required: true, message: '请选择切制形态', trigger: 'change' }],
  209. finalFormOther: [{ required: true, message: '请输入具体切制形态', trigger: 'blur' }],
  210. finalSpecn: [{ required: true, message: '请输入切制尺寸', trigger: 'blur' }],
  211. finalUnit: [{ required: true, message: '请选择切制单位', trigger: 'change' }],
  212. };
  213. } else {
  214. // 类型 1(初加工)只有前三个必填
  215. return baseRules;
  216. }
  217. };
  218. // 根据 type 动态设置校验规则
  219. const type = ref(+props.type);
  220. const rules = ref(getRules());
  221. // 监听 type 变化,重新生成规则
  222. watch(
  223. () => props.type,
  224. (newVal) => {
  225. type.value = newVal;
  226. rules.value = getRules();
  227. },
  228. );
  229. // 关闭弹框
  230. const handleClose = () => {
  231. emit('update:show', false);
  232. resetForm();
  233. };
  234. // 获取标题
  235. const getTitle = () => {
  236. return props.isEdit ? '修改产出信息' : '添加产出信息';
  237. };
  238. // 重置表单
  239. const resetForm = () => {
  240. formData.value = {
  241. specnLevel: '',
  242. capacity: '',
  243. unit: '',
  244. imgs: [],
  245. examinReport: [],
  246. finalFormType: '',
  247. finalFormOther: '',
  248. finalSpecn: '',
  249. finalUnit: '',
  250. id: '',
  251. };
  252. formRef.value?.clearValidate();
  253. };
  254. // 处理统货 checkbox 点击事件
  255. const handleSpecnLevelChange = (checked: boolean) => {
  256. if (checked) {
  257. formData.value.specnLevel = '统货';
  258. } else {
  259. formData.value.specnLevel = '';
  260. }
  261. };
  262. // 跳转到规格等级选择页面
  263. const goToSpecLevel = () => {
  264. uni.$once('updateSpecificationLevel', (res) => {
  265. if (res?.data) {
  266. formData.value.specnLevel = res.data;
  267. }
  268. });
  269. uni.navigateTo({
  270. url: '/tools/specification-level/index',
  271. });
  272. };
  273. // 提交表单
  274. const handleSubmit = async () => {
  275. try {
  276. const valid = await formRef.value?.validate();
  277. if (!valid) return;
  278. // 准备提交数据
  279. const submitData = {
  280. processId: props.processId,
  281. specnLevel: formData.value.specnLevel,
  282. capacity: Number(formData.value.capacity),
  283. unit: formData.value.unit,
  284. imgs: formData.value.imgs.map((item: any) => item.url).join(','),
  285. examinReport: formData.value.examinReport.map((item: any) => ({
  286. fileName: item.fileName || '',
  287. url: item.url || '',
  288. fileSize: item.fileSize || 0,
  289. })),
  290. finalFormType: formData.value.finalFormType,
  291. finalFormOther: formData.value.finalFormOther,
  292. finalSpecn: formData.value.finalSpecn,
  293. finalUnit: formData.value.finalUnit,
  294. };
  295. let res: any;
  296. // 编辑模式调用修改接口
  297. if (props.isEdit && formData.value.id) {
  298. (submitData as any).id = formData.value.id;
  299. res = await useClientRequest.post('/plt-api/app/processOutPut/outputEdit', submitData);
  300. } else {
  301. // 新增模式调用新增接口
  302. res = await useClientRequest.post('/plt-api/app/processOutPut/output', submitData);
  303. }
  304. if (res && res.code === 200) {
  305. uni.showToast({ title: props.isEdit ? '修改成功' : '添加成功', icon: 'success' });
  306. handleClose();
  307. emit('confirm', res.data);
  308. }
  309. } catch (error) {
  310. console.error('提交失败:', error);
  311. }
  312. };
  313. </script>
  314. <style scoped lang="scss">
  315. .search-select-item {
  316. height: 86rpx;
  317. background-color: #fff;
  318. border-radius: 10rpx;
  319. box-sizing: border-box;
  320. padding-left: 16rpx;
  321. padding-right: 16rpx;
  322. padding-top: 14rpx;
  323. padding-bottom: 14rpx;
  324. }
  325. </style>