index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <template>
  2. <view>
  3. <u-modal :show="showModal" ref="uModal" :title="(editOrAdd === 'add' || editOrAdd === 'receptFormAdd') ? '新增' : '编辑'" :asyncClose="false" showCancelButton @cancel="closeDialog" cancelColor="#909399" :confirmText="'确定'" confirmColor="#2979ff" @confirm="confirm" @close="closeDialog" :closeOnClickOverlay="false">
  4. <u--text type="info" text="输入型号可查看价格趋势"></u--text>
  5. <view class="modal_wrap">
  6. <text @click="handleBrandClick" class="item" :class="info.dictLabel ? 'brand' : 'brand placeholder'">{{ info.dictLabel || '品牌' }}</text>
  7. <text class="divider">|</text>
  8. <u--input placeholder="型号" class="item" border="none" v-model="info.model" clearable @blur="handleModelBlur"></u--input>
  9. <text class="divider">|</text>
  10. <u--input class="code-input item" placeholder="编码" border="none" v-model="info.code" clearable></u--input>
  11. </view>
  12. <view class="img_wrap">
  13. <imgs-row-scroll v-if="info.imgsUrl.length > 0" :isShowDeleteIcon="true" @deleteImgInfo="getDeleteImgInfo" imgMode="aspectFill" :totalWidth="400" :images="info.imgsUrl" :previewEnabled="true" :imageWidth="150" :imageHeight="150"></imgs-row-scroll>
  14. <u-upload
  15. @afterRead="afterRead"
  16. name="3"
  17. multiple
  18. :maxCount="10"
  19. ></u-upload>
  20. </view>
  21. <u--input v-if="editOrAdd === 'edit'" class="price" placeholder="价格" border="bottom" v-model="info.price" clearable></u--input>
  22. <view class="charts_box" v-show="chartShow">
  23. <u--text type="primary" :text="`最大价格:${Math.max(...maxPrice)}元`"></u--text>
  24. <u--text type="warning" :text="`最小价格:${Math.min(...minPrice)}元`"></u--text>
  25. <qiun-data-charts type="line" :chartData="chartData" canvasId="trendChart" :opts="opts" :ontouch="true" tooltipFormat="tooltipFormatPrice"
  26. width="700rpx" height="500rpx" backgroundColor="#ffffff" />
  27. </view>
  28. </u-modal>
  29. <brandList ref="brandListRef" @selectedBrand="handleSelectedBrand"></brandList>
  30. </view>
  31. </template>
  32. <script>
  33. import imgsRowScroll from '@/components/imgs-row-scroll/index.vue'
  34. import brandList from '@/components/brand-list/index.vue'
  35. export default {
  36. name: 'AddInquiryDialog',
  37. components: {
  38. imgsRowScroll,
  39. brandList
  40. },
  41. props: {
  42. clueId: {
  43. type: String,
  44. default: ''
  45. },
  46. show: {
  47. type: Boolean,
  48. default: false
  49. },
  50. editOrAdd: {
  51. type: String,
  52. default: ''// edit 编辑(有价格), editForm 编辑询价单(无价格), add 新增询价单, receptFormAdd 新增接收询价单 线索页面:第一次点击是新增(不需要回显),status传1,第二次点击是无价格编辑status传1;接单中心:第一次点击是新增(需要回显)status传1,第二次点击是无价格编辑status传1;只有edit是有价格编辑status传2
  53. },
  54. editInfo: {
  55. type: Object,
  56. default: () => {}
  57. },
  58. type: {
  59. type: Number,
  60. default: 1
  61. },
  62. },
  63. emits: ['submitSuccess'],
  64. data() {
  65. return {
  66. showModal: false,
  67. info: {
  68. model:'',
  69. code:'',
  70. id:'',
  71. price:'',
  72. dictLabel:'',
  73. dictValue:'',
  74. imgsUrl:[]
  75. },
  76. rules: {
  77. brand: [
  78. { required: true, message: '请输入品牌', trigger: 'blur' }
  79. ]
  80. },
  81. chartData:{},
  82. color:[],
  83. opts: {
  84. color: this.color,
  85. padding: [20, 10, 20, 0],
  86. dataLabel: true,
  87. dataPointShape: true,
  88. enableScroll: true,
  89. xAxis: {
  90. disableGrid: true,
  91. scrollShow: true,
  92. itemCount: 10,
  93. rotateLabel: true,
  94. rotateAngle: 45,
  95. },
  96. yAxis: {
  97. gridType: "dash",
  98. dashLength: 7,
  99. },
  100. legend: {
  101. show: false,
  102. type: 'scroll',
  103. orient: 'horizontal',
  104. pageSize: 3,
  105. pageIconSize: 12,
  106. pageIconColor: '#666',
  107. pageIconInactiveColor: '#ccc',
  108. pageTextStyle: {
  109. color: '#666',
  110. fontSize: 12
  111. },
  112. bottom: 0
  113. },
  114. extra: {
  115. line: {
  116. type: "curve",
  117. width: 3,
  118. activeType: "hollow",
  119. linearType: "custom",
  120. onShadow: true,
  121. animation: "horizontal"
  122. },
  123. tooltip:{
  124. legendShow: true,
  125. bgOpacity: 0.6
  126. }
  127. }
  128. },
  129. chartShow: false,
  130. maxPrice: [],
  131. minPrice: [],
  132. }
  133. },
  134. watch: {
  135. show: {
  136. handler(newVal) {
  137. this.showModal = newVal;
  138. },
  139. immediate: true
  140. }
  141. },
  142. methods: {
  143. getChartData() {
  144. uni.$u.api.inquiryChart({
  145. model: this.info.model,
  146. }).then(res => {
  147. if (res.code == 200) {
  148. const response = res.data
  149. this.maxPrice = []
  150. this.minPrice = []
  151. // const response = [
  152. // {
  153. // model:'AAA',
  154. // list:[
  155. // {
  156. // recycleTime: '2023-07-30',
  157. // price: 300,
  158. // },
  159. // {
  160. // recycleTime: '2023-07-31',
  161. // price: 500,
  162. // },
  163. // {
  164. // recycleTime: '2023-08-01',
  165. // price: null,
  166. // },
  167. // {
  168. // recycleTime: '2023-08-02',
  169. // price: 200,
  170. // },
  171. // {
  172. // recycleTime: '2023-08-03',
  173. // price: 300,
  174. // }
  175. // ]
  176. // },
  177. // {
  178. // model:'BBB',
  179. // list:[
  180. // {
  181. // recycleTime: '2023-08-01',
  182. // price:400,
  183. // },
  184. // {
  185. // recycleTime: '2023-08-02',
  186. // price: 100,
  187. // },
  188. // {
  189. // recycleTime: '2023-08-03',
  190. // price: 200,
  191. // }
  192. // ]
  193. // },
  194. // {
  195. // model:'CCC',
  196. // list:[
  197. // {
  198. // recycleTime: '2023-08-01',
  199. // price: 500,
  200. // },
  201. // {
  202. // recycleTime: '2023-08-02',
  203. // price: 400,
  204. // },
  205. // {
  206. // recycleTime: '2023-08-03',
  207. // price: 600,
  208. // }
  209. // ]
  210. // }
  211. // ]
  212. this.color = []
  213. const categories = []
  214. const dateMap = {}
  215. response.forEach(item => {
  216. this.maxPrice.push(item.max)
  217. this.minPrice.push(item.min)
  218. item.list.forEach(i => {
  219. if (!dateMap[i.recycleTime]) {
  220. dateMap[i.recycleTime] = true
  221. categories.push(i.recycleTime)
  222. }
  223. })
  224. })
  225. const series = response.map((item) => {
  226. const color = this.getRandomColor()
  227. this.color.push(color)
  228. const data = categories.map(date => {
  229. const itemData = item.list.find(i => i.recycleTime === date)
  230. return itemData ? itemData.price : null
  231. })
  232. return {
  233. name: item.model,
  234. data: data,
  235. setShadow: [
  236. 3,
  237. 8,
  238. 15,
  239. color
  240. ],
  241. }
  242. })
  243. this.opts.color = this.color
  244. const chartData = {
  245. categories: categories,
  246. series: series
  247. }
  248. this.chartData = JSON.parse(JSON.stringify(chartData))
  249. this.chartShow = true
  250. }
  251. })
  252. },
  253. getRandomColor(){
  254. var letters = '0123456789ABCDEF';
  255. var color = '#';
  256. for (var i = 0; i < 6; i++) {
  257. color += letters[Math.floor(Math.random() * 16)];
  258. }
  259. return color;
  260. },
  261. // 编辑回显
  262. initData() {
  263. this.$nextTick(()=>{
  264. this.info = JSON.parse(JSON.stringify(this.editInfo))
  265. this.showModal = true;
  266. if(this.info.model && this.info.dictValue){
  267. this.getChartData()
  268. }
  269. })
  270. },
  271. // 获取删除图片信息
  272. getDeleteImgInfo(info) {
  273. this.info.imgsUrl = info.newImages
  274. },
  275. handleBrandClick() {
  276. this.$refs.brandListRef.showBrandList();
  277. },
  278. handleSelectedBrand(info) {
  279. this.info.dictLabel = info.dictLabel
  280. this.info.dictValue = info.dictValue
  281. },
  282. // 上传图片
  283. afterRead(info) {
  284. info.file.forEach(item=>{
  285. uni.$u.api.uploadFile(item.url).then((res) => {
  286. this.info.imgsUrl.push(res.data.url);
  287. uni.$u.toast("文件上传成功");
  288. }).catch(() => {
  289. uni.$u.toast("上传文件失败");
  290. })
  291. })
  292. },
  293. // 确认添加
  294. confirm() {
  295. if (!this.info.dictLabel || !this.info.dictValue) {
  296. uni.showToast({
  297. title: '请选择品牌',
  298. icon: 'none'
  299. })
  300. return
  301. }
  302. if (!this.info.model) {
  303. uni.showToast({
  304. title: '请输入型号',
  305. icon: 'none'
  306. })
  307. return
  308. }
  309. if (!this.info.code) {
  310. uni.showToast({
  311. title: '请输入编码',
  312. icon: 'none'
  313. })
  314. return
  315. }
  316. if(this.info.imgsUrl.length == 0){
  317. uni.showToast({
  318. title: '请上传图片',
  319. icon: 'none'
  320. })
  321. return
  322. }
  323. if(this.editOrAdd === 'edit' && !this.info.price){
  324. uni.showToast({
  325. title: '请输入价格',
  326. icon: 'none'
  327. })
  328. return
  329. }
  330. const data = {
  331. clueId: this.clueId,
  332. dictValue: this.info.dictValue,
  333. dictLabel: this.info.dictLabel,
  334. model: this.info.model,
  335. code: this.info.code,
  336. id: (this.editOrAdd === 'edit' || this.editOrAdd === 'editForm') ? this.info.id : '',
  337. price: this.editOrAdd === 'edit' ? this.info.price : '',
  338. imgsUrl:this.info.imgsUrl,
  339. status: this.editOrAdd === 'edit' ? '2' : '1',
  340. type: this.type
  341. }
  342. uni.$u.api.addInquiry(data).then(res => {
  343. if (res.code == 200) {
  344. uni.showToast({
  345. title: '添加成功',
  346. icon: 'success'
  347. })
  348. this.closeDialog()
  349. this.$emit('submitSuccess')
  350. }
  351. })
  352. },
  353. showDialog() {
  354. if (this.editOrAdd === 'edit' || this.editOrAdd === 'editForm' || this.editOrAdd === 'receptFormAdd') {
  355. this.initData();
  356. }else if(this.editOrAdd === 'add'){
  357. this.clearForm()
  358. this.showModal = true;
  359. }
  360. },
  361. clearForm() {
  362. this.info = {
  363. dictLabel:'',
  364. dictValue:'',
  365. model:'',
  366. code:'',
  367. id:'',
  368. price:'',
  369. imgsUrl:[]
  370. }
  371. },
  372. closeDialog() {
  373. this.showModal = false;
  374. this.chartShow = false
  375. this.chartData = {}
  376. },
  377. handleModelBlur() {
  378. if (this.info.model !== ''){
  379. this.getChartData()
  380. }
  381. },
  382. }
  383. };
  384. </script>
  385. <style lang="scss" scoped>
  386. @import './index.scss'
  387. </style>