index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <template>
  2. <view class="oder_form_wrap">
  3. <u-navbar placeholder :autoBack="true" title="发单表单" @rightClick="handleNavSaveClick">
  4. <view class="u-nav-slot" slot="right">
  5. 保存
  6. </view>
  7. </u-navbar>
  8. <view class="form_wrap">
  9. <u--form labelPosition="left" labelWidth="100" :model="form" :rules="rules" ref="form" class="form_wrap"
  10. :errorType="'toast'">
  11. <u-form-item label="省市区" borderBottom>
  12. <pick-regions :defaultRegion="defaultRegion" @getRegion="handleGetRegion">
  13. <view class="region-picker">
  14. <template v-if="form.province">
  15. <u--input :value="form.province + '/' + form.city + '/' + form.area" placeholder="点击选择"
  16. readonly suffixIcon="arrow-right" suffixIconStyle="color : #c0c4cc"></u--input>
  17. </template>
  18. <template v-else>
  19. <u--input placeholder="点击选择" readonly suffixIcon="arrow-right"
  20. suffixIconStyle="color : #c0c4cc"></u--input>
  21. </template>
  22. </view>
  23. </pick-regions>
  24. </u-form-item>
  25. <u-form-item label="详细地址" prop="address" borderBottom>
  26. <u--textarea v-model="form.address" placeholder="请输入详细地址" count confirmType="done"></u--textarea>
  27. </u-form-item>
  28. <u-form-item label="上门时间" prop="visitTime" borderBottom>
  29. <date-time-picker v-model="form.visitTime" :value-format="'YYYY-MM-DD HH:mm:ss'" :type="'datetime'">
  30. </date-time-picker>
  31. </u-form-item>
  32. <u-form-item label="类型" prop="category" borderBottom>
  33. <ld-select :list="categoryDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择类型"
  34. v-model="form.category" :border="false"></ld-select>
  35. <u-icon slot="right" name="arrow-right"></u-icon>
  36. </u-form-item>
  37. <u-form-item label="物品品牌" prop="brand" borderBottom>
  38. <u--input v-model="form.brand" placeholder="请输入物品品牌" border="none"></u--input>
  39. </u-form-item>
  40. <u-form-item label="价格范围" prop="priceRange" borderBottom>
  41. <u--input v-model="form.priceRange" placeholder="请输入价格范围" border="none"></u--input>
  42. </u-form-item>
  43. <u-form-item label="战术选择" prop="tactic" borderBottom>
  44. <ld-select :list="tacticDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择战术"
  45. v-model="form.tactic" :border="false"></ld-select>
  46. <u-icon slot="right" name="arrow-right"></u-icon>
  47. </u-form-item>
  48. <u-form-item label="补充说明" prop="remarks" borderBottom>
  49. <u--textarea v-model="form.remarks" placeholder="请输入补充说明" count confirmType="done"></u--textarea>
  50. </u-form-item>
  51. </u--form>
  52. </view>
  53. <!-- 文件上传区域 -->
  54. <view class="upload_area">
  55. <!-- 聊天记录附件 -->
  56. <order-file-upload title="聊天记录附件" file-type="1" :file-list="form.chatAttachmentList"
  57. @update:fileList="updateChatFiles"
  58. tip-text="上传聊天截图、录音等文件"></order-file-upload>
  59. <!-- 报价附件 -->
  60. <order-file-upload title="报价附件" file-type="2" :file-list="form.quoteAttachmentList"
  61. @update:fileList="updateQuoteFiles"
  62. tip-text="上传报价附件"></order-file-upload>
  63. <!-- 高清图附件 -->
  64. <order-file-upload title="高清图附件" file-type="3" :file-list="form.hdImageAttachmentList"
  65. @update:fileList="updateHdImageFiles"
  66. tip-text="上传物品高清图片"></order-file-upload>
  67. <!-- 其他附件 -->
  68. <order-file-upload title="其他附件" file-type="4" :file-list="form.otherAttachmentList"
  69. @update:fileList="updateOtherFiles"
  70. tip-text="上传其他相关文件"></order-file-upload>
  71. </view>
  72. </view>
  73. </template>
  74. <script>
  75. import orderFileUpload from '@/components/order-file-upload/order-file-upload.vue'
  76. import dateTimePicker from "@/components/dateTimePicker/dateTimePicker.vue"
  77. export default {
  78. components: {
  79. orderFileUpload,
  80. dateTimePicker
  81. },
  82. data() {
  83. return {
  84. defaultRegion: ['广东省', '广州市', '番禺区'],
  85. categoryDict: [],
  86. tacticDict: [],
  87. form: {
  88. clueId: '',
  89. sendDate: '',
  90. website: '',
  91. item: '',
  92. phone: '',
  93. address: '',
  94. visitTime: '',
  95. remarks: '',
  96. category: '',
  97. brand: '',
  98. priceRange: '',
  99. tactic: '',
  100. // 地区信息
  101. province: '',
  102. city: '',
  103. area: '',
  104. // 附件列表
  105. chatAttachmentList: [], // 聊天记录附件
  106. quoteAttachmentList: [], // 报价附件
  107. hdImageAttachmentList: [], // 高清图附件
  108. otherAttachmentList: [] // 其他附件
  109. },
  110. rules: {
  111. sendDate: {
  112. type: 'string',
  113. required: true,
  114. message: '请输入发单日期',
  115. trigger: ['blur', 'change']
  116. },
  117. website: {
  118. type: 'url',
  119. message: '请输入正确的网址格式',
  120. trigger: ['blur', 'change']
  121. },
  122. item: {
  123. type: 'string',
  124. required: true,
  125. message: '请输入物品描述',
  126. trigger: ['blur', 'change']
  127. },
  128. phone: {
  129. type: 'string',
  130. required: true,
  131. message: '请输入联系电话',
  132. trigger: ['blur', 'change']
  133. },
  134. address: {
  135. type: 'string',
  136. required: true,
  137. message: '请输入详细地址',
  138. trigger: ['blur', 'change']
  139. },
  140. visitTime: {
  141. type: 'string',
  142. required: true,
  143. message: '请输入上门时间',
  144. trigger: ['blur', 'change']
  145. },
  146. category: {
  147. type: 'string',
  148. required: true,
  149. message: '请选择类型',
  150. trigger: ['blur', 'change']
  151. },
  152. brand: {
  153. type: 'string',
  154. required: true,
  155. message: '请输入物品品牌',
  156. trigger: ['blur', 'change']
  157. },
  158. tactic: {
  159. type: 'string',
  160. required: true,
  161. message: '请选择战术',
  162. trigger: ['blur', 'change']
  163. }
  164. }
  165. }
  166. },
  167. methods: {
  168. // 获取地区选择
  169. handleGetRegion(region) {
  170. const [provinceData, cityData, areaData] = region;
  171. this.form.province = provinceData.name;
  172. this.form.city = cityData.name;
  173. this.form.area = areaData.name;
  174. // 只在详细地址为空时自动填充省市区
  175. if (!this.form.address || this.form.address.trim() === '') {
  176. this.form.address = this.form.province + this.form.city + this.form.area;
  177. }
  178. },
  179. // 更新各类附件
  180. updateChatFiles(fileList) {
  181. this.form.chatAttachmentList = fileList;
  182. },
  183. updateQuoteFiles(fileList) {
  184. this.form.quoteAttachmentList = fileList;
  185. },
  186. updateHdImageFiles(fileList) {
  187. this.form.hdImageAttachmentList = fileList;
  188. },
  189. updateOtherFiles(fileList) {
  190. this.form.otherAttachmentList = fileList;
  191. },
  192. // 文件变化处理
  193. handleFileChange(data) {
  194. console.log('文件上传变化:', data);
  195. },
  196. // 获取字典数据
  197. async getDicts() {
  198. try {
  199. const [categoryRes, tacticRes] = await Promise.all([
  200. this.$getDicts('crm_form_category'),
  201. this.$getDicts('crm_form_tactic')
  202. ]);
  203. this.categoryDict = categoryRes;
  204. this.tacticDict = tacticRes;
  205. } catch (error) {
  206. console.error('获取字典数据失败:', error);
  207. }
  208. },
  209. // 处理保存
  210. async handleNavSaveClick() {
  211. try {
  212. // 表单验证
  213. await this.$refs.form.validate();
  214. // 合并所有附件
  215. const allAttachments = [
  216. ...this.form.chatAttachmentList,
  217. ...this.form.quoteAttachmentList,
  218. ...this.form.hdImageAttachmentList,
  219. ...this.form.otherAttachmentList
  220. ];
  221. // 准备提交数据
  222. const submitData = {
  223. ...this.form,
  224. uploadList: allAttachments
  225. };
  226. // 调用保存接口
  227. await uni.$u.api.saveClueOrderForm(submitData);
  228. uni.$u.toast('发单记录添加成功');
  229. // 延迟返回
  230. setTimeout(() => {
  231. uni.navigateBack();
  232. }, 1500);
  233. } catch (error) {
  234. console.error('保存失败:', error);
  235. if (error.message) {
  236. uni.$u.toast(error.message);
  237. }
  238. }
  239. }
  240. },
  241. onLoad(option) {
  242. const clueId = option.clueId;
  243. this.form.clueId = clueId;
  244. this.getDicts();
  245. }
  246. }
  247. </script>
  248. <style lang="scss" scoped>
  249. .oder_form_wrap {
  250. background-color: #f5f5f5;
  251. min-height: 100vh;
  252. padding-bottom: 100rpx;
  253. padding-top: 10px;
  254. }
  255. .form_wrap {
  256. background-color: #fff;
  257. border-radius: 16rpx;
  258. overflow: hidden;
  259. }
  260. .upload_area {
  261. padding: 0 20rpx;
  262. margin: 20rpx 0;
  263. }
  264. .bottom_btn {
  265. position: fixed;
  266. bottom: 0;
  267. left: 0;
  268. right: 0;
  269. padding: 20rpx;
  270. background: #fff;
  271. box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
  272. }
  273. .region-picker {
  274. width: 100%;
  275. }
  276. ::v-deep .u-form-item__body {
  277. padding: 20rpx 40rpx;
  278. }
  279. ::v-deep .u-form-item {
  280. border-bottom: 1rpx solid #f5f5f5;
  281. }
  282. ::v-deep .u-form-item:last-child {
  283. border-bottom: none;
  284. }
  285. </style>