work.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <template>
  2. <view class="content">
  3. <up-form :model="form" labelWidth="70" ref="uFormRef" disabled>
  4. <block v-if="workpresetjson.questionedit != 0">
  5. <up-form-item label="故障类型" prop="itemtype" :required="workpresetjson.questionedit == 11">
  6. <view class="options-box">
  7. <view class="option" :class="form.itemtype == item.value ? 'active' : ''"
  8. v-for="item in questionoption" :key="item.value"
  9. @click="clickRadio(item.value, 'itemtype')">
  10. {{ item.value }}
  11. </view>
  12. </view>
  13. </up-form-item>
  14. <up-form-item label="问题编辑" prop="questionedit" :required="workpresetjson.questionedit == 11">
  15. <up-textarea maxlength="499" :disabled="data.status == 1" v-model="form.questionedit"
  16. placeholder="问题编辑" autoHeight height="20" />
  17. </up-form-item>
  18. </block>
  19. <up-form-item v-if="workpresetjson.passcheck != 0" label="合格确认" prop="passcheck"
  20. :required="workpresetjson.passcheck == 11">
  21. <view class="options-box">
  22. <view class="option" :class="form.passcheck == item.value ? 'active' : ''" v-for="item in [
  23. { value: '1', name: '正常' },
  24. { value: '0', name: '异常' }]" :key="item.value" @click="clickRadio(item.value, 'passcheck')">
  25. {{ item.name }}
  26. </view>
  27. </view>
  28. </up-form-item>
  29. <view v-if="workpresetjson.additem != 0">
  30. <up-form-item label="是否更换配件" prop="additem" :required="workpresetjson.additem == 11">
  31. <view class="options-box">
  32. <view class="option" :class="form.additem == item.value ? 'active' : ''" v-for="item in [
  33. { value: '1', name: '是' },
  34. { value: '0', name: '否' }]" :key="item.value" @click="clickRadio(item.value, 'additem')">
  35. {{ item.name }}
  36. </view>
  37. </view>
  38. </up-form-item>
  39. <block v-if="form.additem == 1">
  40. <up-form-item :label="`新配件(${data.newtitems.length})`" prop="newtitems" required>
  41. <view class="options-box">
  42. <view class="option active" hover-class="navigator-hover" @click="toAddItem('newtitems')">
  43. + 去添加新配件
  44. </view>
  45. </view>
  46. </up-form-item>
  47. <accList :list="data.newtitems" :disabled="data.status == 1"
  48. @deleteItem="deleteItem($event, 'newtitems')" />
  49. <up-form-item :label="`旧配件(${data.oldtitems.length})`">
  50. <view class="options-box">
  51. <view class="option active" hover-class="navigator-hover" @click="toAddItem('oldtitems')">
  52. + 去添加旧配件
  53. </view>
  54. </view>
  55. </up-form-item>
  56. <accList :list="data.oldtitems" :disabled="data.status == 1"
  57. @deleteItem="deleteItem($event, 'oldtitems')" />
  58. </block>
  59. </view>
  60. <up-form-item v-if="workpresetjson.confirm != 0" label="确认信息" prop="confirm"
  61. :required="workpresetjson.confirm == 11">
  62. <view class="options-box">
  63. <view class="option" :class="form.confirm == item ? 'active' : ''"
  64. v-for="(item) in workpresetjson.confirm_options" :key="item"
  65. @click="clickRadio(item, 'confirm')">
  66. {{ item }}
  67. </view>
  68. </view>
  69. </up-form-item>
  70. <up-form-item v-if="workpresetjson.amountpay != 0" label="费用支付" prop="amountpay"
  71. :required="workpresetjson.amountpay == 11">
  72. <up-input :disabled="data.status == 1" v-model="form.amountpay" type="number" placeholder="费用支付">
  73. <template #suffix>
  74. </template>
  75. </up-input>
  76. </up-form-item>
  77. <up-form-item v-if="workpresetjson.fileupload != 0" label="拍照" prop="fileupload"
  78. :required="rules.fileupload[0].required">
  79. <up-image v-if="data.status == 1 && data.attinfos.length == 0" :show-loading="true" src="" width="80px"
  80. height="80px" @click="click"></up-image>
  81. <My_upload v-else :disabled="data.status == 1" ref="upload" :fileList="data.attinfos"
  82. @uploadCallback="uploadCallback" />
  83. </up-form-item>
  84. <up-form-item v-if="workpresetjson.textedit != 0" label="文字说明" prop="textedit"
  85. :required="rules.textedit[0].required">
  86. <up-textarea maxlength="499" :disabled="data.status == 1" v-model="form.textedit" placeholder="文字说明"
  87. autoHeight height="20" />
  88. </up-form-item>
  89. </up-form>
  90. <view style="height: 50px;" />
  91. <page-container :show="true" :overlay="false" @beforeleave="beforeleave" />
  92. </view>
  93. </template>
  94. <script setup>
  95. import { ref, reactive, getCurrentInstance, watch } from 'vue';
  96. import { onLoad } from '@dcloudio/uni-app';
  97. import accList from "./modules/products.vue";
  98. const { $Http } = getCurrentInstance().proxy;
  99. const uFormRef = ref(null);
  100. const upload = ref(null);
  101. let formModified = ref(false);
  102. function beforeleave(e) {
  103. if (formModified.value && data.status != '1') {
  104. uni.showModal({
  105. title: '提示',
  106. content: '是否保存当前编辑内容?',
  107. confirmText: '保存',
  108. cancelText: '不保存',
  109. success: function (res) {
  110. if (res.confirm) {
  111. save()
  112. setTimeout(() => {
  113. uni.navigateBack()
  114. }, 500);
  115. } else if (res.cancel) {
  116. uni.navigateBack()
  117. }
  118. }
  119. });
  120. } else {
  121. uni.navigateBack()
  122. }
  123. }
  124. // 去添加配件
  125. function toAddItem(key = 'oldtitems') {
  126. if (data.status == '1') return;
  127. $Http.basicsData = {
  128. selected: key,
  129. newtitems: deepCloneArray(data.newtitems) || [],
  130. oldtitems: deepCloneArray(data.oldtitems) || [],
  131. }
  132. uni.navigateTo({
  133. url: '/pages/select/accessories'
  134. });
  135. $Http.selectAcc = (res) => {
  136. data.newtitems = res.newtitems;
  137. data.oldtitems = res.oldtitems;
  138. form.newtitems = res.newtitems.length ? '1' : '';
  139. uni.navigateBack();
  140. delete $Http.selectAcc
  141. delete $Http.basicsData
  142. }
  143. }
  144. // 帮我写一个[{},{}] 深拷贝的方法
  145. function deepCloneArray(arr) {
  146. return arr.map(item => {
  147. return { ...item };
  148. })
  149. }
  150. // 删除配件
  151. function deleteItem(item, key = 'oldtitems') {
  152. data[key] = data[key].filter(v => v.itemid !== item.itemid);
  153. if (key == 'newtitems') form.newtitems = data.newtitems.length ? '1' : '';
  154. }
  155. const form = reactive({
  156. textedit: '', // 上传文本
  157. confirm: "", // 确认信息
  158. itemtype: "", // 故障类型
  159. questionedit: "", // 问题编辑
  160. additem: "", // 是否更换配件
  161. passcheck: "", //合格确认 异常时 文字和图片必填
  162. amountpay: "", // 费用支付
  163. fileupload: "", // 上传图片
  164. oldtitems: "",//配件
  165. newtitems: "",//配件
  166. });
  167. let keys = {
  168. textedit: 'textcontent', // 文本内容
  169. amountpay: 'amount', // 费用支付
  170. confirm: 'confirm_value', // 确认信息
  171. itemtype: "questionoption",
  172. questionedit: "questionedit",
  173. }
  174. // keys 与 form 互相转换字段
  175. let formToContent = (form) => {
  176. let content = {};
  177. for (let key in form) {
  178. if (keys[key]) {
  179. content[keys[key]] = form[key];
  180. } else {
  181. content[key] = form[key];
  182. }
  183. }
  184. if (content.amount === '') content.amount = 0;
  185. return content;
  186. }
  187. let data = {
  188. attinfos: []
  189. };
  190. let workpresetjson = reactive({});
  191. let rules = reactive({
  192. textedit: [
  193. { required: false, message: '请输入说明', trigger: 'blur' }
  194. ],
  195. fileupload: [
  196. { required: false, message: '请上传图片', trigger: 'change' }
  197. ],
  198. });
  199. const questionoption = ref([]);
  200. function clickRadio() { }
  201. onLoad(() => {
  202. data = reactive($Http.data);
  203. data.status = 1;
  204. delete $Http.data;
  205. form.fileupload = data.attinfos.length ? '1' : '';
  206. uni.setNavigationBarTitle({
  207. title: data.title,
  208. })
  209. workpresetjson = Object.assign(workpresetjson, data.workpresetjson);
  210. if (workpresetjson.additem) {
  211. data.oldtitems = data.detail[0].oldtitems.map(item => {
  212. item.imageUrl = item.attinfos.length ? $Http.getSpecifiedImage(item.attinfos[0]) : ''
  213. return item;
  214. });
  215. data.newtitems = data.detail[0].newtitems.map(item => {
  216. item.imageUrl = item.attinfos.length ? $Http.getSpecifiedImage(item.attinfos[0]) : ''
  217. return item;
  218. });
  219. form.newtitems = data.newtitems.length ? '1' : '';
  220. form.oldtitems = data.oldtitems.length ? '1' : '';
  221. form.additem = form.newtitems || form.oldtitems ? '1' : '0';
  222. }
  223. rules = Object.assign(rules, {
  224. textedit: [
  225. { required: workpresetjson.textedit == 11, message: '请输入说明', trigger: 'blur' },
  226. { min: 2, max: 500, message: '长度在 2 到 500 个字符', trigger: 'blur' }
  227. ],
  228. confirm: [
  229. { required: workpresetjson.confirm == 11, message: '请选择确认信息', trigger: 'change' }
  230. ],
  231. itemtype: [
  232. { required: workpresetjson.questionedit == 11, message: '请选择故障类型', trigger: 'change' }
  233. ],
  234. questionedit: [
  235. { required: workpresetjson.questionedit == 11, message: '请输入问题编辑', trigger: 'blur' },
  236. { min: 2, max: 500, message: '长度在 2 到 500 个字符', trigger: 'blur' }
  237. ],
  238. additem: [
  239. { required: workpresetjson.additem == 11, message: '请选择是否更换配件', trigger: 'change' }
  240. ],
  241. passcheck: [
  242. { required: workpresetjson.passcheck == 11, message: '请选择合格确认', trigger: 'change' }
  243. ],
  244. amountpay: [
  245. { required: workpresetjson.amountpay == 11, message: '请输入费用支付', trigger: 'blur', validator: (rule, value) => value !== '' },
  246. { pattern: /^(0|[1-9]\d*)(\.\d{1,2})?$/, message: '请输入正确的金额', trigger: 'blur' }
  247. ],
  248. fileupload: [
  249. { required: workpresetjson.fileupload == 11, message: '请上传图片', trigger: 'change' }
  250. ],
  251. additem: [{ required: workpresetjson.additem == 11, message: '请选择是否更换配件', trigger: 'change' }]
  252. })
  253. setTimeout(() => {
  254. if (data.passcheck == '0') {
  255. rules.textedit[0].required = true;
  256. rules.fileupload[0].required = true;
  257. }
  258. uFormRef.value.setRules(rules);
  259. });
  260. if (workpresetjson.questionedit) $Http.getClass(workpresetjson.questionoption).then(res => {
  261. questionoption.value = res.data;
  262. if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
  263. })
  264. for (let key in keys) {
  265. if (data[keys[key]]) {
  266. form[key] = data[keys[key]];
  267. console.log(key, form[key])
  268. }
  269. }
  270. });
  271. </script>
  272. <style lang="scss" scoped>
  273. .content {
  274. width: 100vw;
  275. padding: 20px;
  276. box-sizing: border-box;
  277. min-height: 100vh;
  278. background: #fff;
  279. .picker {
  280. width: 100%;
  281. // border-bottom: 1px solid #dadbde;
  282. font-size: 32rpx;
  283. color: #606266;
  284. padding: 9px;
  285. border-radius: 8rpx;
  286. }
  287. .title {
  288. font-size: 34rpx;
  289. color: #4773EE;
  290. margin: 20rpx 0;
  291. font-weight: bold;
  292. }
  293. .options-box {
  294. position: relative;
  295. top: -6rpx;
  296. display: flex;
  297. flex-wrap: wrap;
  298. width: 100%;
  299. box-sizing: border-box;
  300. .option {
  301. border: 1px solid #dadbde;
  302. border-radius: 8rpx;
  303. padding: 10rpx 20rpx;
  304. margin-right: 18rpx;
  305. margin-top: 12rpx;
  306. transition: background-color 0.3s, color 0.3s, border-color 0.3s;
  307. text-align: center;
  308. min-width: 80rpx;
  309. }
  310. .active {
  311. background: #006EF7;
  312. color: #fff;
  313. border-color: #006EF7;
  314. }
  315. }
  316. .but-box {
  317. display: flex;
  318. align-items: center;
  319. justify-content: space-around;
  320. margin-top: 40rpx;
  321. .but-box-item {
  322. width: 45%;
  323. }
  324. }
  325. }
  326. </style>