outputInfo.vue 16 KB

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