changeMsg.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <template>
  2. <view class="content">
  3. <up-form :model="form" labelWidth="70" ref="uFormRef">
  4. <view class="title" style="margin-top: 0;">
  5. 服务信息
  6. </view>
  7. <up-form-item label="服务类型" :required="rules.servicetype[0].required" prop="servicetype">
  8. <up-radio-group v-model="form.servicetype" @change="servicetypeChange">
  9. <up-radio :customStyle="{ marginLeft: '12px' }" v-for="(item) in servertypes" :key="item"
  10. :label="item" :name="item">
  11. </up-radio>
  12. </up-radio-group>
  13. </up-form-item>
  14. <up-form-item label="产品品类" :required="rules.class1[0].required" prop="class1">
  15. <up-radio-group v-model="form.class1">
  16. <up-radio :customStyle="{ marginLeft: '12px' }" v-for="(item) in class1" :key="item.value"
  17. :label="item.value" :name="item.value">
  18. </up-radio>
  19. </up-radio-group>
  20. </up-form-item>
  21. <up-form-item label="服务地址" :required="rules.province[0].required" prop="province">
  22. <picker class="picker" mode="region" :value="[form.province, form.city, form.county]"
  23. @change="changeRegion">
  24. {{ [form.province, form.city, form.county].join("-") || '选择省市县' }}
  25. </picker>
  26. </up-form-item>
  27. <view style="margin-top: -30rpx;">
  28. <up-form-item label="" prop="address">
  29. <up-textarea maxlength="499" v-model="form.address" placeholder="详细地址" autoHeight height="20" />
  30. </up-form-item>
  31. </view>
  32. <up-form-item label="联系人" :required="rules.scenecontact[0].required" prop="scenecontact">
  33. <up-input v-model="form.scenecontact" placeholder="联系人" clearable />
  34. </up-form-item>
  35. <up-form-item label="联系人电话" :required="rules.scenecontactphonenumber[0].required"
  36. prop="scenecontactphonenumber">
  37. <up-input type="number" v-model="form.scenecontactphonenumber" placeholder="联系人电话" clearable />
  38. </up-form-item>
  39. <up-form-item label="服务距离(单程)" prop="servicemileage">
  40. <up-input v-model="form.servicemileage" placeholder="服务距离(单程)" clearable>
  41. <template #suffix>
  42. Km
  43. </template>
  44. </up-input>
  45. </up-form-item>
  46. <view class="title">
  47. 产品信息
  48. </view>
  49. <up-form-item label="序列号" :required="rules.sku[0].required" prop="sku">
  50. <up-input v-model="sku" placeholder="序列号" clearable @blur="skuConfirm">
  51. <template #suffix>
  52. <up-icon name="scan" color="#2979ff" size="28" @click="openScan" />
  53. </template>
  54. </up-input>
  55. </up-form-item>
  56. <up-form-item label="产品名称" prop="itemname">
  57. <up-input v-model="form.itemname" disabled placeholder="选择产品">
  58. </up-input>
  59. </up-form-item>
  60. <up-form-item label="产品型号" prop="model">
  61. <up-input v-model="form.model" disabled placeholder="型号" />
  62. </up-form-item>
  63. <up-form-item v-if="form.servicetype != '安装'" label="保修卡号" prop="cardno">
  64. <up-input v-model="form.cardno" disabled placeholder="保修卡号" />
  65. </up-form-item>
  66. </up-form>
  67. <view style="padding-bottom: 50px;width: 350rpx;margin: 40rpx auto 0;" @click="save">
  68. <My-button text="保存" :loading="loading" />
  69. </view>
  70. </view>
  71. </template>
  72. <script setup>
  73. import { ref, reactive, getCurrentInstance } from 'vue';
  74. const { $Http } = getCurrentInstance().proxy;
  75. import { onLoad } from '@dcloudio/uni-app';
  76. const uFormRef = ref(null);
  77. const sku = ref('');
  78. const form = reactive({
  79. class1: '', // 产品品类
  80. class2: '', // 故障类型
  81. servicetype: '', // 服务类型
  82. address: "", // 详细地址
  83. province: '', // 省份
  84. city: '', // 城市
  85. county: '', // 区县
  86. scenecontact: '', // 联系人
  87. scenecontactphonenumber: '', // 联系人电话
  88. sku: '', // 序列号
  89. 'customername': "", // 客户名称
  90. 'customerphonenumber': "", // 客户电话
  91. 'itemid': "", // 产品ID
  92. 'itemname': "", // 产品名称
  93. 'itemno': "", // 产品编号
  94. 'model': "", // 型号
  95. 'unitname': "", // 计量单位
  96. 'spec': "", // 规格
  97. enterprisename: "", // 经销商
  98. cardno: "",// 保修卡号
  99. servicemileage: ""
  100. });
  101. const rules = reactive({
  102. class1: [{ required: true, message: '请选择产品品类', trigger: 'change' }],
  103. class2: [{ required: false, message: "请选择故障类型", trigger: 'change' }],
  104. servicetype: [{ required: true, message: '请选择服务类型', trigger: 'change' }],
  105. province: [{ required: true, message: '请选择省市县', trigger: 'change' }],
  106. address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }],
  107. scenecontact: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
  108. sku: [{ required: false, message: '请输入序列号', trigger: 'change' }],
  109. scenecontactphonenumber: [{ required: true, message: '请输入联系人电话', trigger: 'blur', pattern: /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/, message: '请输入正确的手机号码' }],
  110. });
  111. // 切换服务类型
  112. function servicetypeChange(type) {
  113. // rules.class2[0].required = type == '维修';
  114. rules.sku[0].required = type == '安装';
  115. uFormRef.value.setRules(rules);
  116. }
  117. const class1 = ref(''),
  118. servertypes = ref(['维修', '清洗']),
  119. class2 = ref('');
  120. let sa_workorderid = 0;
  121. onLoad((options) => {
  122. sa_workorderid = options.id;
  123. getDetail()
  124. $Http.getClass('prodclass1').then(res => {
  125. class1.value = res.data;
  126. if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
  127. });
  128. $Http.getClass('faulttype').then(res => {
  129. class2.value = res.data;
  130. uFormRef.value.setRules(rules);
  131. if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
  132. });
  133. });
  134. let detail = reactive({});
  135. // 保存
  136. let loading = ref(false);
  137. function save() {
  138. if (loading.value) return;
  139. uFormRef.value.validate().then(valid => {
  140. if (valid) {
  141. let content = {
  142. "sa_workorderid": sa_workorderid,
  143. sa_serviceorderid: detail.sa_serviceorderid,
  144. ...form,
  145. servicemileage: form.servicemileage || 0,
  146. phonenumber: form.customerphonenumber || '',
  147. };
  148. content.customerphonenumber = content.customerphonenumber || content.phonenumber;
  149. content.name = content.customername || '';
  150. content.sa_customersid = content.sa_customersid == '' ? content.sa_customersid : 0;
  151. loading.value = true;
  152. $Http.basic({
  153. "id": "20230208140003",
  154. content
  155. }).then(res => {
  156. loading.value = false;
  157. console.log("保存工单", res);
  158. uni.showToast({ title: res.code !== 1 ? res.msg : "保存成功", icon: 'none', mask: res.code == 1 });
  159. let workorderids = uni.getStorageSync('workorderids') || [];
  160. workorderids.push(sa_workorderid);
  161. uni.setStorageSync('workorderids', workorderids);
  162. if (res.code == 1) setTimeout(() => {
  163. uni.navigateBack();
  164. }, 500);
  165. }).catch(err => {
  166. loading.value = false;
  167. console.error("保存工单失败", err);
  168. uni.showToast({ title: '保存失败,请稍后重试', icon: 'none' });
  169. });
  170. }
  171. })
  172. }
  173. let disabled = ref(false);
  174. function getDetail() {
  175. $Http.basic({ "id": "20230208140103", "content": { "nocache": true, sa_workorderid } }).then(res => {
  176. console.log("工单详情", res)
  177. if (res.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
  178. detail = reactive(res.data);
  179. rules.class2[0].required = detail.type == '维修';
  180. if (detail.type == '安装') {
  181. servertypes.value = ['安装'];
  182. rules.sku[0].required = true
  183. } else {
  184. $Http.getClass('servertype').then(res1 => {
  185. servertypes.value = res1.data.map(v => v.value).filter(v => v != '安装')
  186. if (res1.code !== 1) return uni.showToast({ title: res.msg, icon: 'none' });
  187. });
  188. }
  189. if (res.data.servicetype)
  190. for (const key in form) {
  191. if (detail[key] !== undefined) {
  192. form[key] = detail[key];
  193. if (key == 'sku') {
  194. sku.value = detail[key];
  195. }
  196. }
  197. }
  198. if (detail.type == '安装') {
  199. let id = detail.sa_workorderid,
  200. workorderids = uni.getStorageSync('workorderids') || [];
  201. let hasId = workorderids.findIndex(item => item == id);
  202. if (hasId == -1) {
  203. form.sku = '';
  204. sku.value = '';
  205. }
  206. }
  207. disabled.value = detail.item ? true : false
  208. })
  209. }
  210. function changeRegion(e) {
  211. form.province = e.detail.value[0];
  212. form.city = e.detail.value[1];
  213. form.county = e.detail.value[2];
  214. }
  215. function skuConfirm() {
  216. if (sku.value) {
  217. if (sku.value == '') return;
  218. $Http.basic({
  219. "id": 20221215101003,
  220. "content": {
  221. "where": {
  222. "sku": sku.value.trim()
  223. }
  224. }
  225. }).then(res => {
  226. console.log("查询sku", res)
  227. uni.hideLoading();
  228. if (res.code !== 1) {
  229. uni.showToast({ title: res.msg, icon: 'none' })
  230. form.sku = '';
  231. sku.value = '';
  232. return
  233. };
  234. if (res.data.length === 0 || res.data[0].sku !== sku.value.trim()) {
  235. uni.showToast({ title: '未查询到对应的产品信息,请确认序列号是否正确', icon: 'none' });
  236. form.sku = '';
  237. sku.value = '';
  238. return;
  239. }
  240. changeItem(res.data[0]);
  241. })
  242. } else {
  243. form.sku = '';
  244. sku.value = '';
  245. }
  246. }
  247. function changeItem(item) {
  248. let list = ['sku', 'cardno', 'itemid', 'itemname', 'itemno', 'sa_customersid'];
  249. list.forEach(key => {
  250. if (key == 'sku') sku.value = item[key] || '';
  251. form[key] = item[key] || '';
  252. });
  253. uFormRef.value.clearValidate('sku');
  254. }
  255. function openScan() {
  256. uni.scanCode({
  257. onlyFromCamera: true,
  258. scanType: ['qrCode', 'barCode'],
  259. success: (res) => {
  260. console.log("扫码结果", res);
  261. if (res.result) {
  262. form.sku = res.result;
  263. skuConfirm();
  264. } else {
  265. uni.showToast({ title: '扫码失败,请重试', icon: 'none' });
  266. }
  267. },
  268. fail: (err) => {
  269. console.error("扫码失败", err);
  270. uni.showToast({ title: '扫码失败,请重试', icon: 'none' });
  271. }
  272. });
  273. }
  274. </script>
  275. <style lang="scss" scoped>
  276. .content {
  277. width: 100vw;
  278. padding: 20px;
  279. box-sizing: border-box;
  280. min-height: 100vh;
  281. background: #fff;
  282. .picker {
  283. width: 100%;
  284. border: 1px solid #dadbde;
  285. font-size: 32rpx;
  286. color: #606266;
  287. padding: 9px;
  288. border-radius: 8rpx;
  289. }
  290. .title {
  291. font-size: 34rpx;
  292. color: #4773EE;
  293. margin: 20rpx 0;
  294. font-weight: bold;
  295. }
  296. }
  297. .product {
  298. padding: 20rpx;
  299. background: #fff;
  300. margin: 10rpx 0;
  301. border-radius: 8rpx;
  302. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  303. .itemname {
  304. font-size: 32rpx;
  305. color: #333;
  306. font-weight: bold;
  307. margin-bottom: 10rpx;
  308. }
  309. .row {
  310. font-size: 28rpx;
  311. color: #666;
  312. margin-top: 8rpx;
  313. }
  314. }
  315. </style>