Commit 1d9333b6b2d4c1e70dd38ca5d2947abdcac8861b

Authored by 史婷婷
2 parents 255bc6f1 754bc0ae

Merge remote-tracking branch 'origin/cjerp-1.0_20251220' into publish_cjerp

Too many changes to show.

To preserve performance only 43 of 64 files are displayed.

... ... @@ -81,12 +81,6 @@
81 81 <Host>localhost</Host>
82 82 <Port>5050</Port>
83 83 </configuration>
84   - <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
85   - <module name="" />
86   - <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
87   - <option name="PROGRAM_PARAMETERS" />
88   - <method />
89   - </configuration>
90 84 <configuration default="true" type="Application" factoryName="Application">
91 85 <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
92 86 <method v="2">
... ... @@ -115,6 +109,15 @@
115 109 <option name="Make" enabled="true" />
116 110 </method>
117 111 </configuration>
  112 + <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType">
  113 + <module name="" />
  114 + <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
  115 + <option name="PROGRAM_PARAMETERS" />
  116 + <predefined_log_file enabled="true" id="idea.log" />
  117 + <method v="2">
  118 + <option name="Make" enabled="true" />
  119 + </method>
  120 + </configuration>
118 121 </component>
119 122 <component name="SharedIndexes">
120 123 <attachedChunks>
... ... @@ -156,7 +159,15 @@
156 159 <component name="TypeScriptGeneratedFilesManager">
157 160 <option name="version" value="3" />
158 161 </component>
159   - <component name="VcsContentAnnotationSettings">
160   - <option name="myLimit" value="2678400000" />
  162 + <component name="Vcs.Log.Tabs.Properties">
  163 + <option name="TAB_STATES">
  164 + <map>
  165 + <entry key="MAIN">
  166 + <value>
  167 + <State />
  168 + </value>
  169 + </entry>
  170 + </map>
  171 + </option>
161 172 </component>
162 173 </project>
\ No newline at end of file
... ...
... ... @@ -5,7 +5,7 @@ import { getToken } from '@/utils/auth'
5 5
6 6
7 7 /**
8   - * 根据编号获取数据字段
  8 + * 根据字典编号获取数据字段
9 9 * @param code
10 10 */
11 11 export function getDicByCodeApi(code) {
... ... @@ -41,11 +41,26 @@ export function selectorCityApi() {
41 41 })
42 42 }
43 43 /**
44   - * 回去城市接口 省市区 一次性返回
  44 + * 获取菜单
45 45 */
46 46 export function getMenusApi() {
47 47 return request({
48 48 url: `/auth/menus`,
49 49 method: 'get'
50 50 })
  51 +}
  52 +
  53 +/**
  54 + * 生成编号
  55 + * @param type
  56 + * 客户池编号 5
  57 + */
  58 +export function generateCodeApi(type) {
  59 + return request({
  60 + url: `/component/generate/code`,
  61 + method: 'get',
  62 + params: {
  63 + type
  64 + },
  65 + })
51 66 }
\ No newline at end of file
... ...
... ... @@ -20,6 +20,15 @@ export const statusMap = {
20 20 }
21 21
22 22 const baseUrl = '/contract';
  23 +// 查询当前人所在办事处
  24 +export function getDeptApi(params) {
  25 + return request({
  26 + url: `/system/dept/getDept`,
  27 + method: 'get',
  28 + params
  29 + })
  30 +}
  31 +
23 32 // 查询合同框架列表
24 33 export function queryApi(params) {
25 34 return request({
... ...
  1 +import request from '@/utils/request'
  2 +import { ContentTypeEnum } from '@/utils/httpEnum';
  3 +
  4 +const baseUrl = '/basedata/customer';
  5 +// 查询列表
  6 +export function queryApi(params) {
  7 + return request({
  8 + url: baseUrl + `/query`,
  9 + method: 'get',
  10 + params
  11 + })
  12 +}
  13 +
  14 +// 根据ID查询详情数据
  15 +export function getDetailApi(id) {
  16 + return request({
  17 + url: baseUrl,
  18 + method: 'get',
  19 + params: { id }
  20 + })
  21 +}
  22 +
  23 +// 新增保存
  24 +export function createApi(params) {
  25 + return request({
  26 + url: baseUrl,
  27 + method: 'post',
  28 + data: params,
  29 + contentType: ContentTypeEnum.FORM_URLENCODED
  30 + })
  31 +}
  32 +
  33 +
  34 +// 修改保存
  35 +export function updateApi(params) {
  36 + return request({
  37 + url: baseUrl,
  38 + method: 'put',
  39 + data: params,
  40 + contentType: ContentTypeEnum.FORM_URLENCODED
  41 + })
  42 +}
  43 +
  44 +// 停用
  45 +export function unableApi(id) {
  46 + return request({
  47 + url: baseUrl + '/unable',
  48 + method: 'patch',
  49 + data: {
  50 + id
  51 + },
  52 + contentType: ContentTypeEnum.FORM_URLENCODED
  53 + })
  54 +}
  55 +
  56 +// 启用
  57 +export function enableApi(id) {
  58 + return request({
  59 + url: baseUrl + '/enable',
  60 + method: 'patch',
  61 + data: {
  62 + id
  63 + },
  64 + contentType: ContentTypeEnum.FORM_URLENCODED
  65 + })
  66 +}
... ...
... ... @@ -139,7 +139,7 @@ export default {
139 139 })
140 140 } else if (this.source === 'user') {
141 141 // 人员表
142   - const params = { pageIndex, pageSize, name, username: name }
  142 + const params = { pageIndex, pageSize, name }
143 143 return userSelector(params).then(res => {
144 144 const _data = res.data || {}
145 145 const records = _data.datas || _data.records || _data.list || []
... ...
... ... @@ -106,6 +106,38 @@
106 106 }
107 107 },
108 108 {
  109 + "path": "pages/customer/index",
  110 + "style": {
  111 + "navigationBarTitleText": "客户信息",
  112 + "navigationBarBackgroundColor": "#ffffff",
  113 + "navigationBarTextStyle": "black"
  114 + }
  115 + },
  116 + {
  117 + "path": "pages/customer/add",
  118 + "style": {
  119 + "navigationBarTitleText": "新增客户信息",
  120 + "navigationBarBackgroundColor": "#ffffff",
  121 + "navigationBarTextStyle": "black"
  122 + }
  123 + },
  124 + {
  125 + "path": "pages/customer/detail",
  126 + "style": {
  127 + "navigationBarTitleText": "客户信息详情",
  128 + "navigationBarBackgroundColor": "#ffffff",
  129 + "navigationBarTextStyle": "black"
  130 + }
  131 + },
  132 + {
  133 + "path": "pages/customer/modify",
  134 + "style": {
  135 + "navigationBarTitleText": "编辑客户信息",
  136 + "navigationBarBackgroundColor": "#ffffff",
  137 + "navigationBarTextStyle": "black"
  138 + }
  139 + },
  140 + {
109 141 "path": "pages/credit_manage/index",
110 142 "style": {
111 143 "navigationBarTitleText": "客户资信管理",
... ... @@ -616,6 +648,14 @@
616 648 "navigationBarBackgroundColor": "#ffffff",
617 649 "navigationBarTextStyle": "black"
618 650 }
  651 + },
  652 + {
  653 + "path": "pages/message/detail",
  654 + "style": {
  655 + "navigationBarTitleText": "消息详情",
  656 + "navigationBarBackgroundColor": "#ffffff",
  657 + "navigationBarTextStyle": "black"
  658 + }
619 659 }
620 660 ],
621 661 "subPackages": [
... ...
... ... @@ -82,7 +82,7 @@
82 82 </uni-list-item>
83 83 <uni-list-item title="变更说明">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="form.changeDescription" placeholder="请输入变更说明" :inputBorder="false" />
  85 + <uni-easyinput type="textarea" v-model="form.changeDescription" placeholder="请输入变更说明" :inputBorder="false" />
86 86 </template>
87 87 </uni-list-item>
88 88 </view>
... ... @@ -344,6 +344,31 @@ export default {
344 344 return false
345 345 }
346 346 }
  347 + const has = (v) => v !== undefined && v !== null && String(v).trim() !== ''
  348 + if (has(it.thicknessTolPos) && has(it.thicknessTolNeg)) {
  349 + const pos = Number(it.thicknessTolPos)
  350 + const neg = Number(it.thicknessTolNeg)
  351 + if (!(pos > neg)) {
  352 + uni.showToast({ title: `产品第${i + 1}条:厚度公差上限需大于下限`, icon: 'none' })
  353 + return false
  354 + }
  355 + }
  356 + if (has(it.widthTolPos) && has(it.widthTolNeg)) {
  357 + const pos = Number(it.widthTolPos)
  358 + const neg = Number(it.widthTolNeg)
  359 + if (!(pos > neg)) {
  360 + uni.showToast({ title: `产品第${i + 1}条:宽度公差上限需大于下限`, icon: 'none' })
  361 + return false
  362 + }
  363 + }
  364 + if (has(it.lengthTolPos) && has(it.lengthTolNeg)) {
  365 + const pos = Number(it.lengthTolPos)
  366 + const neg = Number(it.lengthTolNeg)
  367 + if (!(pos > neg)) {
  368 + uni.showToast({ title: `产品第${i + 1}条:长度公差上限需大于下限`, icon: 'none' })
  369 + return false
  370 + }
  371 + }
347 372 }
348 373 return true
349 374 },
... ...
... ... @@ -81,7 +81,7 @@
81 81 </uni-list-item>
82 82 <uni-list-item title="变更说明">
83 83 <template v-slot:footer>
84   - <uni-easyinput v-model="form.changeDescription" placeholder="请输入变更说明" :inputBorder="false" />
  84 + <uni-easyinput type="textarea" v-model="form.changeDescription" placeholder="请输入变更说明" :inputBorder="false" />
85 85 </template>
86 86 </uni-list-item>
87 87 </view>
... ... @@ -264,6 +264,31 @@ export default {
264 264 return false
265 265 }
266 266 }
  267 + const has = (v) => v !== undefined && v !== null && String(v).trim() !== ''
  268 + if (has(it.thicknessTolPos) && has(it.thicknessTolNeg)) {
  269 + const pos = Number(it.thicknessTolPos)
  270 + const neg = Number(it.thicknessTolNeg)
  271 + if (!(pos > neg)) {
  272 + uni.showToast({ title: `产品第${i + 1}条:厚度公差上限需大于下限`, icon: 'none' })
  273 + return false
  274 + }
  275 + }
  276 + if (has(it.widthTolPos) && has(it.widthTolNeg)) {
  277 + const pos = Number(it.widthTolPos)
  278 + const neg = Number(it.widthTolNeg)
  279 + if (!(pos > neg)) {
  280 + uni.showToast({ title: `产品第${i + 1}条:宽度公差上限需大于下限`, icon: 'none' })
  281 + return false
  282 + }
  283 + }
  284 + if (has(it.lengthTolPos) && has(it.lengthTolNeg)) {
  285 + const pos = Number(it.lengthTolPos)
  286 + const neg = Number(it.lengthTolNeg)
  287 + if (!(pos > neg)) {
  288 + uni.showToast({ title: `产品第${i + 1}条:长度公差上限需大于下限`, icon: 'none' })
  289 + return false
  290 + }
  291 + }
267 292 }
268 293 return true
269 294 },
... ...
... ... @@ -42,20 +42,20 @@
42 42 @blur="onNonNegativeNumberBlur(item, idx, 'thickness')" />
43 43 </template>
44 44 </uni-list-item>
45   - <uni-list-item title="厚度公差 +(mm)">
  45 + <uni-list-item title="厚度公差上限(mm)">
46 46 <template v-slot:footer>
47   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" placeholder="请输入厚度公差 +"
  47 + <uni-easyinput type="number" v-model="item.thicknessTolPos" placeholder="请输入厚度公差上限"
48 48 :inputBorder="false"
49   - @input="onNonNegativeNumberInput($event, item, idx, 'thicknessTolPos')"
50   - @blur="onNonNegativeNumberBlur(item, idx, 'thicknessTolPos')" />
  49 + @input="onRealNumberInput($event, item, idx, 'thicknessTolPos')"
  50 + @blur="onRealNumberBlur(item, idx, 'thicknessTolPos')" />
51 51 </template>
52 52 </uni-list-item>
53   - <uni-list-item title="厚度公差 -(mm)">
  53 + <uni-list-item title="厚度公差下限(mm)">
54 54 <template v-slot:footer>
55   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" placeholder="请输入厚度公差 -"
  55 + <uni-easyinput type="number" v-model="item.thicknessTolNeg" placeholder="请输入厚度公差下限"
56 56 :inputBorder="false"
57   - @input="onNonNegativeNumberInput($event, item, idx, 'thicknessTolNeg')"
58   - @blur="onNonNegativeNumberBlur(item, idx, 'thicknessTolNeg')" />
  57 + @input="onRealNumberInput($event, item, idx, 'thicknessTolNeg')"
  58 + @blur="onRealNumberBlur(item, idx, 'thicknessTolNeg')" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="宽度(mm)">
... ... @@ -65,20 +65,20 @@
65 65 @blur="onNonNegativeNumberBlur(item, idx, 'width')" />
66 66 </template>
67 67 </uni-list-item>
68   - <uni-list-item title="宽度公差 +(mm)">
  68 + <uni-list-item title="宽度公差上限(mm)">
69 69 <template v-slot:footer>
70   - <uni-easyinput type="digit" v-model="item.widthTolPos" placeholder="请输入宽度公差 +"
  70 + <uni-easyinput type="number" v-model="item.widthTolPos" placeholder="请输入宽度公差上限"
71 71 :inputBorder="false"
72   - @input="onNonNegativeNumberInput($event, item, idx, 'widthTolPos')"
73   - @blur="onNonNegativeNumberBlur(item, idx, 'widthTolPos')" />
  72 + @input="onRealNumberInput($event, item, idx, 'widthTolPos')"
  73 + @blur="onRealNumberBlur(item, idx, 'widthTolPos')" />
74 74 </template>
75 75 </uni-list-item>
76   - <uni-list-item title="宽度公差 -(mm)">
  76 + <uni-list-item title="宽度公差下限(mm)">
77 77 <template v-slot:footer>
78   - <uni-easyinput type="digit" v-model="item.widthTolNeg" placeholder="请输入宽度公差 -"
  78 + <uni-easyinput type="number" v-model="item.widthTolNeg" placeholder="请输入宽度公差下限"
79 79 :inputBorder="false"
80   - @input="onNonNegativeNumberInput($event, item, idx, 'widthTolNeg')"
81   - @blur="onNonNegativeNumberBlur(item, idx, 'widthTolNeg')" />
  80 + @input="onRealNumberInput($event, item, idx, 'widthTolNeg')"
  81 + @blur="onRealNumberBlur(item, idx, 'widthTolNeg')" />
82 82 </template>
83 83 </uni-list-item>
84 84 <uni-list-item title="长度(mm)">
... ... @@ -88,20 +88,20 @@
88 88 @blur="onNonNegativeNumberBlur(item, idx, 'length')" />
89 89 </template>
90 90 </uni-list-item>
91   - <uni-list-item title="长度公差 +(mm)">
  91 + <uni-list-item title="长度公差上限(mm)">
92 92 <template v-slot:footer>
93   - <uni-easyinput type="digit" v-model="item.lengthTolPos" placeholder="请输入长度公差 +"
  93 + <uni-easyinput type="number" v-model="item.lengthTolPos" placeholder="请输入长度公差上限"
94 94 :inputBorder="false"
95   - @input="onNonNegativeNumberInput($event, item, idx, 'lengthTolPos')"
96   - @blur="onNonNegativeNumberBlur(item, idx, 'lengthTolPos')" />
  95 + @input="onRealNumberInput($event, item, idx, 'lengthTolPos')"
  96 + @blur="onRealNumberBlur(item, idx, 'lengthTolPos')" />
97 97 </template>
98 98 </uni-list-item>
99   - <uni-list-item title="长度公差 -(mm)">
  99 + <uni-list-item title="长度公差下限(mm)">
100 100 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" placeholder="请输入长度公差 -"
  101 + <uni-easyinput type="number" v-model="item.lengthTolNeg" placeholder="请输入长度公差下限"
102 102 :inputBorder="false"
103   - @input="onNonNegativeNumberInput($event, item, idx, 'lengthTolNeg')"
104   - @blur="onNonNegativeNumberBlur(item, idx, 'lengthTolNeg')" />
  103 + @input="onRealNumberInput($event, item, idx, 'lengthTolNeg')"
  104 + @blur="onRealNumberBlur(item, idx, 'lengthTolNeg')" />
105 105 </template>
106 106 </uni-list-item>
107 107 <uni-list-item title="状态">
... ... @@ -178,22 +178,26 @@
178 178 <view class="value value-spec">
179 179 <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
180 180 <view v-if="item.thickness" class="value-spec_box">
181   - <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  181 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">{{ item.thicknessTolPos > 0 ? '+' + item.thicknessTolPos : item.thicknessTolPos }}
182 182 </view>
183   - <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  183 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">{{ item.thicknessTolNeg > 0 ? '+' + item.thicknessTolNeg : item.thicknessTolNeg }}
184 184 </view>
185 185 </view>
186 186 <view v-if="item.width" class="value-spec_val p12">*</view>
187 187 <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
188 188 <view v-if="item.width" class="value-spec_box">
189   - <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
190   - <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  189 + <view v-if="item.widthTolPos" class="value-spec_box_1">{{ item.widthTolPos > 0 ? '+' + item.widthTolPos : item.widthTolPos }}
  190 + </view>
  191 + <view v-if="item.widthTolNeg" class="value-spec_box_2">{{ item.widthTolNeg > 0 ? '+' + item.widthTolNeg : item.widthTolNeg }}
  192 + </view>
191 193 </view>
192 194 <view v-if="item.length" class="value-spec_val p12">*</view>
193 195 <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
194 196 <view v-if="item.length" class="value-spec_box">
195   - <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
196   - <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  197 + <view v-if="item.lengthTolPos" class="value-spec_box_1">{{ item.lengthTolPos > 0 ? '+' + item.lengthTolPos : item.lengthTolPos }}
  198 + </view>
  199 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">{{ item.lengthTolNeg > 0 ? '+' + item.lengthTolNeg : item.lengthTolNeg }}
  200 + </view>
197 201 </view>
198 202 </view>
199 203 </view>
... ... @@ -274,7 +278,7 @@ export default {
274 278 const init = Array.isArray(this.list) && this.list.length > 0 ? this.list.map(v => ({ ...this.defaultItem(), ...v, collapsed: false })) : [{ ...this.defaultItem(), collapsed: false }]
275 279 this.items = init
276 280 },
277   - methods: {
  281 + methods: {
278 282 defaultItem() {
279 283 return {
280 284 id: '',
... ... @@ -302,7 +306,6 @@ export default {
302 306 },
303 307
304 308 onAdd() {
305   - if (this.items.length >= this.max) return uni.showToast({ title: `最多添加${this.max}个`, icon: 'none' })
306 309 const obj = this.defaultItem()
307 310 obj.collapsed = true
308 311 this.items.push(obj)
... ... @@ -358,6 +361,25 @@ export default {
358 361 if (isNaN(num) || num < 0) item[field] = '0'
359 362 if (typeof idx === 'number') this.$set(this.items, idx, { ...item })
360 363 },
  364 + onRealNumberInput(val, item, idx, field) {
  365 + let s = String(val != null ? val : (item && item[field]) || '')
  366 + const neg = s.trim().startsWith('-')
  367 + s = s.replace(/[^0-9.\-]/g, '')
  368 + s = s.replace(/(?!^)-/g, '')
  369 + s = s.replace(/(\..*)\./g, '$1')
  370 + if (s.startsWith('.')) s = '0' + s
  371 + if (s.startsWith('-.')) s = '-0.' + s.slice(2)
  372 + if (neg && !s.startsWith('-')) s = '-' + s.replace(/-/g, '')
  373 + item[field] = s
  374 + if (typeof idx === 'number') this.$set(this.items, idx, { ...item })
  375 + },
  376 + onRealNumberBlur(item, idx, field) {
  377 + const s = String((item && item[field]) || '')
  378 + if (s === '') { if (typeof idx === 'number') this.$set(this.items, idx, { ...item }); return }
  379 + const n = Number(s)
  380 + if (isNaN(n)) item[field] = ''
  381 + if (typeof idx === 'number') this.$set(this.items, idx, { ...item })
  382 + },
361 383 toggleViewCollapse() {
362 384 this.collapsedView = !this.collapsedView
363 385 },
... ...
... ... @@ -21,7 +21,12 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
24   -
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
25 30 <uni-list-item title="订货日期">
26 31 <template v-slot:footer>
27 32 <uni-datetime-picker type="date" v-model="form.orderDate" />
... ... @@ -39,7 +44,23 @@
39 44 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 45 </template>
41 46 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
  47 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  48 + <template v-slot:body>
  49 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  50 + </template>
  51 + <template v-slot:footer>
  52 + <view class="serial-number-row">
  53 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  54 + </view>
  55 + </template>
  56 + </uni-list-item>
  57 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  58 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  59 + <template v-slot:body>
  60 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  61 + </template>
  62 + </uni-list-item>
  63 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 64 <uni-list-item title="合计人民币金额(大写)">
44 65 <template v-slot:footer>
45 66 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +229,12 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 229 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 230 import ProductRel from './productRel.vue'
210 231 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
  232 +import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements,getDeptApi } from '@/api/contract'
212 233 import { getDicByCodes } from '@/utils/dic'
213 234 import { formatCurrencyToChinese } from '@/utils/common'
214 235 import { workshopQueryApi } from '@/api/devManage'
  236 +import { getArea } from '@/api/credit_manage.js'
  237 +
215 238
216 239 export default {
217 240 name: 'AddContractForeignStd',
... ... @@ -223,7 +246,11 @@ export default {
223 246 supplier: '',
224 247 supplierName: '',
225 248 buyer: '',
  249 + region: '',
  250 + regionName: '',
226 251 buyerName: '',
  252 + stockUpCompanyId: '',
  253 + stockUpCompanyName: '',
227 254 orderDate: '',
228 255 deliveryDate: '',
229 256 designatedConsignee: '',
... ... @@ -249,6 +276,8 @@ export default {
249 276 pieceWeightHead: '',
250 277 surface: '',
251 278 tolerance: '',
  279 + deptName: '',
  280 + deptId: '',
252 281 },
253 282 supplierList: [],
254 283 specialTermsList: [],
... ... @@ -263,12 +292,15 @@ export default {
263 292 productList: [],
264 293 customerRemarks: [],
265 294 defaultRemark: '',
  295 + regionOptions: [],
266 296 }
267 297 },
268 298 created() {
269 299 this.loadSuppliers()
270 300 this.loadExtraOptions()
271 301 this.initCode()
  302 + this.getDept()
  303 + this.loadRegionOptions()
272 304 this.form.orderDate = this.formatDate(new Date())
273 305 this.$nextTick(() => {
274 306 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -318,6 +350,24 @@ export default {
318 350 },
319 351 },
320 352 methods: {
  353 + async loadRegionOptions() {
  354 + try {
  355 + const res = await getArea()
  356 + const list = res.data || []
  357 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  358 + } catch (e) {
  359 + this.regionOptions = []
  360 + }
  361 + },
  362 + // 查询当前人所在办事处
  363 + getDept() {
  364 + getDeptApi().then(res => {
  365 + if (res.code === 200) {
  366 + this.form.deptName = res.data.name || ''
  367 + this.form.deptId = res.data.id || ''
  368 + }
  369 + })
  370 + },
321 371 getHistory() {
322 372 if (!this.productLineList.length || !this.productLineList[0].productId) {
323 373 return;
... ... @@ -403,7 +453,7 @@ export default {
403 453 },
404 454 displayLabel(field) {
405 455 const m = this.form
406   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂' }
  456 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
407 457 const val = m[field]
408 458 return val ? String(val) : map[field]
409 459 },
... ... @@ -448,6 +498,8 @@ export default {
448 498 setSheet('单价中是否已包含运费', this.yesNoList)
449 499 } else if (field === 'historyRemarks') {
450 500 setSheet('历史备注', this.customerRemarks)
  501 + }else if (field === 'region') {
  502 + setSheet('区域', this.regionOptions)
451 503 }
452 504 },
453 505 onSheetConfirm({ value, label }) {
... ... @@ -466,6 +518,8 @@ export default {
466 518 let config = {}
467 519 if (fieldKey === 'buyer') {
468 520 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  521 + } else if (fieldKey === 'stockUpCompanyId') {
  522 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
469 523 }
470 524 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
471 525 this.sheet.visible = false
... ... @@ -476,7 +530,17 @@ export default {
476 530 const _fieldKey = this.relate.fieldKey
477 531 const first = (items && items.length > 0) ? items[0] : null
478 532 this.form[_fieldKey] = (first && first.id) ? first.id : ''
479   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  533 +
  534 + if (_fieldKey === 'stockUpCompanyId') {
  535 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  536 + } else {
  537 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  538 + }
  539 +
  540 + if (_fieldKey === 'buyer') {
  541 + this.form.stockUpCompanyId = (first && first.id) ? first.id : ''
  542 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  543 + }
480 544 },
481 545 onRadioSelect(field, nameField, opt) {
482 546 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -532,10 +596,12 @@ export default {
532 596 { key: 'code', label: '编号' },
533 597 { key: 'supplier', label: '供方' },
534 598 { key: 'buyer', label: '需方' },
  599 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
535 600 { key: 'orderDate', label: '订货日期' },
536 601 { key: 'unit', label: '单位' },
537 602 { key: 'workshopId', label: '生产厂' },
538 603 { key: 'specialTerms', label: '特别条款要求' },
  604 + { key: 'region', label: '区域' },
539 605 ]
540 606 for (const it of checks) {
541 607 const val = this.form[it.key]
... ... @@ -561,6 +627,7 @@ export default {
561 627 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
562 628 }
563 629 }
  630 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
564 631 return true
565 632 }
566 633 }
... ...
... ... @@ -10,11 +10,17 @@
10 10 }}</text></view>
11 11 <view class="row"><text class="label">需方</text><text class="value">{{ detail.buyerName || '-'
12 12 }}</text></view>
  13 + <view class="row"><text class="label">备货单位/人(生产标准)</text><text class="value">{{ detail.stockUpCompanyName || '-'
  14 + }}</text></view>
13 15 <view class="row"><text class="label">订货日期</text><text class="value">{{ detail.orderDate }}</text>
14 16 </view>
15 17 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
16 18 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName || '-'
17 19 }}</text></view>
  20 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  21 + }}</text></view>
  22 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  23 + }}</text></view>
18 24 </view>
19 25
20 26 <view class="section1">
... ... @@ -133,10 +139,15 @@ export default {
133 139 supplierName: '',
134 140 buyer: '',
135 141 buyerName: '',
  142 + stockUpCompanyId: '',
  143 + stockUpCompanyName: '',
136 144 orderDate: '',
137 145 unit: '',
138 146 workshopId: '',
139 147 workshopName: '',
  148 + region: '',
  149 + regionName: '',
  150 + deptName: '',
140 151 designatedConsignee: '',
141 152 specialTerms: '',
142 153 specialTermsName: '',
... ... @@ -380,6 +391,9 @@ export default {
380 391 this.detail = {
381 392 ...this.detail,
382 393 ...data,
  394 + stockUpCompanyName: data.stockUpCompanyName || '',
  395 + regionName: data.regionName || '',
  396 + deptName: data.deptName || '',
383 397 includesPackagingFeeName, includesTransportFeeName,
384 398 destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',
385 399 destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '',
... ...
... ... @@ -21,6 +21,12 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
24 30
25 31 <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
26 32 @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
... ... @@ -28,6 +34,22 @@
28 34 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
29 35 </template>
30 36 </uni-list-item>
  37 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  38 + <template v-slot:body>
  39 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  40 + </template>
  41 + <template v-slot:footer>
  42 + <view class="serial-number-row">
  43 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  44 + </view>
  45 + </template>
  46 + </uni-list-item>
  47 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  48 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  49 + <template v-slot:body>
  50 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  51 + </template>
  52 + </uni-list-item>
31 53
32 54 <uni-list-item title="订货日期">
33 55 <template v-slot:footer>
... ... @@ -40,7 +62,7 @@
40 62 <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
41 63 </template>
42 64 </uni-list-item>
43   - <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  65 + <ProductRel ref="productRel" mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
44 66 <uni-list-item title="合计人民币金额(大写)">
45 67 <template v-slot:footer>
46 68 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false"
... ... @@ -196,6 +218,7 @@ import { getContractApi, updateContractApi } from '@/api/contract'
196 218 import { getDicByCodes } from '@/utils/dic'
197 219 import { formatCurrencyToChinese } from '@/utils/common'
198 220 import { workshopQueryApi } from '@/api/devManage'
  221 +import { getArea } from '@/api/credit_manage.js'
199 222 export default {
200 223 name: 'ModifyContractForeignStd',
201 224 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -209,8 +232,14 @@ export default {
209 232 supplierName: '',
210 233 buyer: '',
211 234 buyerName: '',
  235 + stockUpCompanyId: '',
  236 + stockUpCompanyName: '',
212 237 workshopId: '',
213 238 workshopName: '',
  239 + region: '',
  240 + regionName: '',
  241 + deptName: '',
  242 + deptId: '',
214 243 orderDate: '',
215 244 deliveryDate: '',
216 245 designatedConsignee: '',
... ... @@ -251,7 +280,8 @@ export default {
251 280 totalAmountIncludingTax: 0,
252 281 productLineList: [],
253 282 newProductLineList: [],
254   - productList: []
  283 + productList: [],
  284 + regionOptions: []
255 285 }
256 286 },
257 287 onLoad(query) {
... ... @@ -260,6 +290,7 @@ export default {
260 290 created() {
261 291 this.loadSuppliers()
262 292 this.loadExtraOptions()
  293 + this.loadRegionOptions()
263 294 this.loadDetail()
264 295 this.$nextTick(() => {
265 296 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -268,6 +299,15 @@ export default {
268 299 })
269 300 },
270 301 methods: {
  302 + async loadRegionOptions() {
  303 + try {
  304 + const res = await getArea()
  305 + const list = res.data || []
  306 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  307 + } catch (e) {
  308 + this.regionOptions = []
  309 + }
  310 + },
271 311 async loadDetail() {
272 312 if (!this.id) return
273 313 try {
... ... @@ -284,6 +324,8 @@ export default {
284 324 supplierName: m.supplierName || '',
285 325 buyer: m.buyer || (m.customer && m.customer.id) || '',
286 326 buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  327 + stockUpCompanyId: m.stockUpCompanyId || '',
  328 + stockUpCompanyName: m.stockUpCompanyName || '',
287 329 orderDate: m.orderDate || '',
288 330 designatedConsignee: m.designatedConsignee || '',
289 331 specialTerms: m.specialTerms || '',
... ... @@ -313,6 +355,10 @@ export default {
313 355 packaging: m.packaging || '',
314 356 workshopId: m.workshopId || '',
315 357 workshopName: m.workshopName || '',
  358 + region: m.region || '',
  359 + regionName: m.regionName || '',
  360 + deptName: m.deptName || '',
  361 + deptId: m.deptId || '',
316 362 }
317 363 const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
318 364 this.productLineList = lines
... ... @@ -368,7 +414,7 @@ export default {
368 414 },
369 415 displayLabel(field) {
370 416 const m = this.form
371   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂' }
  417 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
372 418 const val = m[field]
373 419 return val ? String(val) : map[field]
374 420 },
... ... @@ -397,6 +443,8 @@ export default {
397 443 setSheet('单价中是否已包含包装费', this.yesNoList)
398 444 } else if (field === 'includesTransportFee') {
399 445 setSheet('单价中是否已包含运费', this.yesNoList)
  446 + } else if (field === 'region') {
  447 + setSheet('区域', this.regionOptions)
400 448 }
401 449 },
402 450 onSheetConfirm({ value, label }) {
... ... @@ -410,6 +458,8 @@ export default {
410 458 let config = {}
411 459 if (fieldKey === 'buyer') {
412 460 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  461 + } else if (fieldKey === 'stockUpCompanyId') {
  462 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
413 463 }
414 464 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
415 465 this.sheet.visible = false
... ... @@ -420,7 +470,12 @@ export default {
420 470 const _fieldKey = this.relate.fieldKey
421 471 const first = (items && items.length > 0) ? items[0] : null
422 472 this.form[_fieldKey] = (first && first.id) ? first.id : ''
423   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  473 +
  474 + if (_fieldKey === 'stockUpCompanyId') {
  475 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  476 + } else {
  477 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  478 + }
424 479 },
425 480 onRadioSelect(field, nameField, opt) {
426 481 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -436,9 +491,11 @@ export default {
436 491 { key: 'code', label: '编号' },
437 492 { key: 'supplier', label: '供方' },
438 493 { key: 'buyer', label: '需方' },
  494 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
439 495 { key: 'orderDate', label: '订货日期' },
440 496 { key: 'unit', label: '单位' },
441 497 { key: 'workshopId', label: '生产厂' },
  498 + { key: 'region', label: '区域' },
442 499 { key: 'specialTerms', label: '特别条款要求' },
443 500 ]
444 501 for (const it of checks) {
... ... @@ -466,6 +523,7 @@ export default {
466 523 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
467 524 }
468 525 }
  526 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
469 527 return true
470 528 },
471 529 async onSubmit() {
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度(mm)">
57 57 <template v-slot:footer>
58   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差上限(mm)">
62 62 <template v-slot:footer>
63   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  63 + <uni-easyinput type="text" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差上限" @input="onNumberInput(idx, 'thicknessTolPos')" @blur="onNumberBlur(idx, 'thicknessTolPos', 9)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差下限(mm)">
68 68 <template v-slot:footer>
69   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  69 + <uni-easyinput type="text" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差下限" @input="onNumberInput(idx, 'thicknessTolNeg')" @blur="onNumberBlur(idx, 'thicknessTolNeg', 9)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度(mm)">
74 74 <template v-slot:footer>
75   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差上限(mm)">
79 79 <template v-slot:footer>
80   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  80 + <uni-easyinput type="text" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNumberInput(idx, 'widthTolPos')" @blur="onNumberBlur(idx, 'widthTolPos', 9)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差下限(mm)">
84 84 <template v-slot:footer>
85   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  85 + <uni-easyinput type="text" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNumberInput(idx, 'widthTolNeg')" @blur="onNumberBlur(idx, 'widthTolNeg', 9)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度(mm)">
89 89 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差上限(mm)">
94 94 <template v-slot:footer>
95   - <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  95 + <uni-easyinput type="text" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差上限" @input="onNumberInput(idx, 'lengthTolPos')" @blur="onNumberBlur(idx, 'lengthTolPos', 9)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差下限(mm)">
100 100 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  101 + <uni-easyinput type="text" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差下限" @input="onNumberInput(idx, 'lengthTolNeg')" @blur="onNumberBlur(idx, 'lengthTolNeg', 9)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 9)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 9)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="外贸加工费">
... ... @@ -302,6 +302,62 @@ export default {
302 302 this.$set(this.items, idx, it)
303 303 if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
304 304 },
  305 + onNumberInput(idx, field) {
  306 + const it = this.items[idx]
  307 + if (!it) return
  308 + let v = String(it[field] != null ? it[field] : '')
  309 + v = v.replace(/[^0-9.-]/g, '')
  310 + if (v.lastIndexOf('-') > 0) {
  311 + const hasMinusAtStart = v.startsWith('-')
  312 + v = v.replace(/-/g, '')
  313 + if (hasMinusAtStart) v = '-' + v
  314 + }
  315 + if ((v.match(/\./g) || []).length > 1) {
  316 + const firstDotIndex = v.indexOf('.')
  317 + v = v.substring(0, firstDotIndex + 1) + v.substring(firstDotIndex + 1).replace(/\./g, '')
  318 + }
  319 + if (v.startsWith('.')) v = '0' + v
  320 + if (v.startsWith('-.')) v = '-0' + v.substring(1)
  321 + it[field] = v
  322 + this.$set(this.items, idx, it)
  323 + },
  324 + onNumberBlur(idx, field, digits) {
  325 + const it = this.items[idx]
  326 + if (!it) return
  327 + const raw = it[field]
  328 + if (raw === '' || raw === null || raw === undefined || raw === '-') {
  329 + this.$set(this.items, idx, it)
  330 + return
  331 + }
  332 + let num = this.toNumber(raw)
  333 + if (isNaN(num)) num = 0
  334 + const rounded = this.round(num, digits)
  335 + it[field] = rounded
  336 + this.$set(this.items, idx, it)
  337 + },
  338 + validate() {
  339 + for (let i = 0; i < this.items.length; i++) {
  340 + const it = this.items[i]
  341 + const check = (pos, neg, label) => {
  342 + if (pos !== '' && pos !== null && pos !== undefined &&
  343 + neg !== '' && neg !== null && neg !== undefined) {
  344 + if (Number(pos) <= Number(neg)) {
  345 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  346 + }
  347 + }
  348 + return null
  349 + }
  350 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  351 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  352 +
  353 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  354 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  355 +
  356 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  357 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  358 + }
  359 + return true
  360 + },
305 361 formatCurrency(val) {
306 362 if (val == null || val === '') return ''
307 363 const num = Number(val)
... ...
... ... @@ -22,6 +22,13 @@
22 22 </template>
23 23 </uni-list-item>
24 24
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
25 32 <uni-list-item title="订货日期">
26 33 <template v-slot:footer>
27 34 <uni-datetime-picker type="date" v-model="form.orderDate" />
... ... @@ -39,7 +46,24 @@
39 46 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 47 </template>
41 48 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
  49 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  50 + <template v-slot:body>
  51 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  52 + </template>
  53 + <template v-slot:footer>
  54 + <view class="serial-number-row">
  55 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  56 + </view>
  57 + </template>
  58 + </uni-list-item>
  59 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  60 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  61 + <template v-slot:body>
  62 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  63 + </template>
  64 + </uni-list-item>
  65 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate"
  66 + @change="onProductsChange" :options="productList" />
43 67 <uni-list-item title="合计人民币金额(大写)">
44 68 <template v-slot:footer>
45 69 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +232,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 232 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 233 import ProductRel from './productRel.vue'
210 234 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi, getCustomerSpecificQualityRequirements,getCustomerRemarks } from '@/api/contract'
  235 +import { getRetailCodeApi, createContractApi, getCustomerSpecificQualityRequirements,getCustomerRemarks, getDeptApi } from '@/api/contract'
212 236 import { getDicByCodes } from '@/utils/dic'
213 237 import { formatCurrencyToChinese } from '@/utils/common'
214 238 import { workshopQueryApi } from '@/api/devManage'
  239 +import { getArea } from '@/api/credit_manage.js'
215 240
216 241 export default {
217 242 name: 'AddContractForeignStock',
... ... @@ -224,6 +249,8 @@ export default {
224 249 supplierName: '',
225 250 buyer: '',
226 251 buyerName: '',
  252 + stockUpCompanyId: '',
  253 + stockUpCompanyName: '',
227 254 orderDate: '',
228 255 deliveryDate: '',
229 256 designatedConsignee: '',
... ... @@ -242,7 +269,11 @@ export default {
242 269 destinationLabel: '',
243 270 workshopIdName: '',
244 271 workshopId: '',
245   - component: '',
  272 + deptName: '',
  273 + deptId: '',
  274 + region: '',
  275 + regionName: '',
  276 + remarks: '',
246 277 packaging: '',
247 278 performance: '',
248 279 pieceWeightHead: '',
... ... @@ -263,12 +294,15 @@ export default {
263 294 productList: [],
264 295 customerRemarks: [],
265 296 defaultRemark: '',
  297 + regionOptions: [],
266 298 }
267 299 },
268 300 created() {
269 301 this.loadSuppliers()
270 302 this.loadExtraOptions()
271 303 this.initCode()
  304 + this.getDept()
  305 + this.loadRegionOptions()
272 306 this.form.orderDate = this.formatDate(new Date())
273 307 this.$nextTick(() => {
274 308 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -318,6 +352,24 @@ export default {
318 352 },
319 353 },
320 354 methods: {
  355 + async loadRegionOptions() {
  356 + try {
  357 + const res = await getArea()
  358 + const list = res.data || []
  359 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  360 + } catch (e) {
  361 + this.regionOptions = []
  362 + }
  363 + },
  364 + // 查询当前人所在办事处
  365 + getDept() {
  366 + getDeptApi().then(res => {
  367 + if (res.code === 200) {
  368 + this.form.deptName = res.data.name || ''
  369 + this.form.deptId = res.data.id || ''
  370 + }
  371 + })
  372 + },
321 373 getHistory() {
322 374 console.log('this.productLineList', this.productLineList[0].productId)
323 375 if (!this.productLineList.length || !this.productLineList[0].productId) {
... ... @@ -405,7 +457,7 @@ export default {
405 457 },
406 458 displayLabel(field) {
407 459 const m = this.form
408   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂' }
  460 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
409 461 const val = m[field]
410 462 return val ? String(val) : map[field]
411 463 },
... ... @@ -450,6 +502,8 @@ export default {
450 502 setSheet('单价中是否已包含运费', this.yesNoList)
451 503 } else if (field === 'historyRemarks') {
452 504 setSheet('历史备注', this.customerRemarks)
  505 + }else if (field === 'region') {
  506 + setSheet('区域', this.regionOptions)
453 507 }
454 508 },
455 509 onSheetConfirm({ value, label }) {
... ... @@ -468,6 +522,8 @@ export default {
468 522 let config = {}
469 523 if (fieldKey === 'buyer') {
470 524 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  525 + } else if (fieldKey === 'stockUpCompanyId') {
  526 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
471 527 }
472 528 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
473 529 this.sheet.visible = false
... ... @@ -478,7 +534,17 @@ export default {
478 534 const _fieldKey = this.relate.fieldKey
479 535 const first = (items && items.length > 0) ? items[0] : null
480 536 this.form[_fieldKey] = (first && first.id) ? first.id : ''
481   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  537 +
  538 + if (_fieldKey === 'stockUpCompanyId') {
  539 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  540 + } else {
  541 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  542 + }
  543 +
  544 + if (_fieldKey === 'buyer') {
  545 + this.form.stockUpCompanyId = (first && first.id) ? first.id : ''
  546 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  547 + }
482 548 },
483 549 onRadioSelect(field, nameField, opt) {
484 550 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -534,9 +600,11 @@ export default {
534 600 { key: 'code', label: '编号' },
535 601 { key: 'supplier', label: '供方' },
536 602 { key: 'buyer', label: '需方' },
  603 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
537 604 { key: 'orderDate', label: '订货日期' },
538 605 { key: 'unit', label: '单位' },
539 606 { key: 'workshopId', label: '生产厂' },
  607 + { key: 'region', label: '区域' },
540 608 { key: 'specialTerms', label: '特别条款要求' },
541 609 ]
542 610 for (const it of checks) {
... ... @@ -544,6 +612,7 @@ export default {
544 612 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
545 613 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
546 614 }
  615 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
547 616 const list = Array.isArray(this.productLineList) ? this.productLineList : []
548 617 if (list.length === 0) {
549 618 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -15,11 +15,17 @@
15 15 }}</text></view>
16 16 <view class="row"><text class="label">需方</text><text class="value">{{ detail.buyerName || '-'
17 17 }}</text></view>
  18 + <view class="row"><text class="label">备货单位/人(生产标准)</text><text class="value">{{ detail.stockUpCompanyName || '-'
  19 + }}</text></view>
18 20 <view class="row"><text class="label">订货日期</text><text class="value">{{ detail.orderDate }}</text>
19 21 </view>
20 22 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
21 23 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName || '-'
22 24 }}</text></view>
  25 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  26 + }}</text></view>
  27 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  28 + }}</text></view>
23 29 </view>
24 30
25 31 <view class="section1">
... ... @@ -147,10 +153,15 @@ export default {
147 153 supplierName: '',
148 154 buyer: '',
149 155 buyerName: '',
  156 + stockUpCompanyId: '',
  157 + stockUpCompanyName: '',
150 158 orderDate: '',
151 159 unit: '',
152 160 workshopId: '',
153 161 workshopName: '',
  162 + deptName: '',
  163 + region: '',
  164 + regionName: '',
154 165 designatedConsignee: '',
155 166 specialTerms: '',
156 167 specialTermsName: '',
... ... @@ -466,6 +477,9 @@ export default {
466 477 this.detail = {
467 478 ...this.detail,
468 479 ...data,
  480 + stockUpCompanyName: data.stockUpCompanyName || '',
  481 + regionName: data.regionName || '',
  482 + deptName: data.deptName || '',
469 483 includesPackagingFeeName, includesTransportFeeName,
470 484 destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',
471 485 destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '',
... ...
... ... @@ -22,12 +22,35 @@
22 22 </template>
23 23 </uni-list-item>
24 24
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
25 32 <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
26 33 @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
27 34 <template v-slot:body>
28 35 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
29 36 </template>
30 37 </uni-list-item>
  38 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  39 + <template v-slot:body>
  40 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  41 + </template>
  42 + <template v-slot:footer>
  43 + <view class="serial-number-row">
  44 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  45 + </view>
  46 + </template>
  47 + </uni-list-item>
  48 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  49 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  50 + <template v-slot:body>
  51 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  52 + </template>
  53 + </uni-list-item>
31 54
32 55 <uni-list-item title="订货日期">
33 56 <template v-slot:footer>
... ... @@ -41,7 +64,8 @@
41 64 </template>
42 65 </uni-list-item>
43 66
44   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  67 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate"
  68 + :list="productLineList" @change="onProductsChange" :options="productList" />
45 69
46 70 <uni-list-item title="合计人民币金额(大写)">
47 71 <template v-slot:footer>
... ... @@ -198,6 +222,8 @@ import { getContractApi, updateContractApi } from '@/api/contract'
198 222 import { getDicByCodes } from '@/utils/dic'
199 223 import { formatCurrencyToChinese } from '@/utils/common'
200 224 import { workshopQueryApi } from '@/api/devManage'
  225 +import { getArea } from '@/api/credit_manage.js'
  226 +
201 227 export default {
202 228 name: 'ModifyContractForeignStock',
203 229 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -211,8 +237,14 @@ export default {
211 237 supplierName: '',
212 238 buyer: '',
213 239 buyerName: '',
  240 + stockUpCompanyId: '',
  241 + stockUpCompanyName: '',
214 242 workshopId: '',
215 243 workshopName: '',
  244 + region: '',
  245 + regionName: '',
  246 + deptName: '',
  247 + deptId: '',
216 248 orderDate: '',
217 249 deliveryDate: '',
218 250 designatedConsignee: '',
... ... @@ -253,7 +285,8 @@ export default {
253 285 totalAmountIncludingTax: 0,
254 286 productLineList: [],
255 287 newProductLineList: [],
256   - productList: []
  288 + productList: [],
  289 + regionOptions: []
257 290 }
258 291 },
259 292 onLoad(query) {
... ... @@ -262,6 +295,7 @@ export default {
262 295 created() {
263 296 this.loadSuppliers()
264 297 this.loadExtraOptions()
  298 + this.loadRegionOptions()
265 299 this.loadDetail()
266 300 this.$nextTick(() => {
267 301 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -270,6 +304,15 @@ export default {
270 304 })
271 305 },
272 306 methods: {
  307 + async loadRegionOptions() {
  308 + try {
  309 + const res = await getArea()
  310 + const list = res.data || []
  311 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  312 + } catch (e) {
  313 + this.regionOptions = []
  314 + }
  315 + },
273 316 async loadDetail() {
274 317 if (!this.id) return
275 318 try {
... ... @@ -286,6 +329,8 @@ export default {
286 329 supplierName: m.supplierName || '',
287 330 buyer: m.buyer || (m.customer && m.customer.id) || '',
288 331 buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  332 + stockUpCompanyId: m.stockUpCompanyId || '',
  333 + stockUpCompanyName: m.stockUpCompanyName || '',
289 334 orderDate: m.orderDate || '',
290 335 designatedConsignee: m.designatedConsignee || '',
291 336 specialTerms: m.specialTerms || '',
... ... @@ -315,6 +360,10 @@ export default {
315 360 packaging: m.packaging || '',
316 361 workshopId: m.workshopId || '',
317 362 workshopName: m.workshopName || '',
  363 + region: m.region || '',
  364 + regionName: m.regionName || '',
  365 + deptName: m.deptName || '',
  366 + deptId: m.deptId || '',
318 367 }
319 368 const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
320 369 this.productLineList = lines
... ... @@ -370,7 +419,7 @@ export default {
370 419 },
371 420 displayLabel(field) {
372 421 const m = this.form
373   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂' }
  422 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
374 423 const val = m[field]
375 424 return val ? String(val) : map[field]
376 425 },
... ... @@ -399,6 +448,8 @@ export default {
399 448 setSheet('单价中是否已包含包装费', this.yesNoList)
400 449 } else if (field === 'includesTransportFee') {
401 450 setSheet('单价中是否已包含运费', this.yesNoList)
  451 + } else if (field === 'region') {
  452 + setSheet('区域', this.regionOptions)
402 453 }
403 454 },
404 455 onSheetConfirm({ value, label }) {
... ... @@ -412,6 +463,8 @@ export default {
412 463 let config = {}
413 464 if (fieldKey === 'buyer') {
414 465 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  466 + } else if (fieldKey === 'stockUpCompanyId') {
  467 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
415 468 }
416 469 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
417 470 this.sheet.visible = false
... ... @@ -422,7 +475,12 @@ export default {
422 475 const _fieldKey = this.relate.fieldKey
423 476 const first = (items && items.length > 0) ? items[0] : null
424 477 this.form[_fieldKey] = (first && first.id) ? first.id : ''
425   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  478 +
  479 + if (_fieldKey === 'stockUpCompanyId') {
  480 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  481 + } else {
  482 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  483 + }
426 484 },
427 485 onRadioSelect(field, nameField, opt) {
428 486 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -438,9 +496,11 @@ export default {
438 496 { key: 'code', label: '编号' },
439 497 { key: 'supplier', label: '供方' },
440 498 { key: 'buyer', label: '需方' },
  499 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
441 500 { key: 'orderDate', label: '订货日期' },
442 501 { key: 'unit', label: '单位' },
443 502 { key: 'workshopId', label: '生产厂' },
  503 + { key: 'region', label: '区域' },
444 504 { key: 'specialTerms', label: '特别条款要求' },
445 505 ]
446 506 for (const it of checks) {
... ... @@ -448,6 +508,7 @@ export default {
448 508 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
449 509 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
450 510 }
  511 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
451 512 const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
452 513 if (list.length === 0) {
453 514 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -55,51 +55,53 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度(mm)">
57 57 <template v-slot:footer>
58   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差上限(mm)">
62 62 <template v-slot:footer>
63   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  63 + <uni-easyinput type="text" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差上限" @input="onNumberInput(idx, 'thicknessTolPos')" @blur="onNumberBlur(idx, 'thicknessTolPos', 9)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差下限(mm)">
68 68 <template v-slot:footer>
69   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  69 + <uni-easyinput type="text" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差下限" @input="onNumberInput(idx, 'thicknessTolNeg')" @blur="onNumberBlur(idx, 'thicknessTolNeg', 9)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度(mm)">
74 74 <template v-slot:footer>
75   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差上限(mm)">
79 79 <template v-slot:footer>
80   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  80 + <uni-easyinput type="text" v-model="item.widthTolPos" :inputBorder="false"
  81 + placeholder="请输入宽度公差上限" @input="onNumberInput(idx, 'widthTolPos')" @blur="onNumberBlur(idx, 'widthTolPos', 9)" />
81 82 </template>
82 83 </uni-list-item>
83 84 <uni-list-item title="宽度公差下限(mm)">
84 85 <template v-slot:footer>
85   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  86 + <uni-easyinput type="text" v-model="item.widthTolNeg" :inputBorder="false"
  87 + placeholder="请输入宽度公差下限" @input="onNumberInput(idx, 'widthTolNeg')" @blur="onNumberBlur(idx, 'widthTolNeg', 9)" />
86 88 </template>
87 89 </uni-list-item>
88 90 <uni-list-item title="长度(mm)">
89 91 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  92 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
91 93 </template>
92 94 </uni-list-item>
93 95 <uni-list-item title="长度公差上限(mm)">
94 96 <template v-slot:footer>
95   - <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  97 + <uni-easyinput type="text" v-model="item.lengthTolPos" :inputBorder="false"
  98 + placeholder="请输入长度公差上限" @input="onNumberInput(idx, 'lengthTolPos')" @blur="onNumberBlur(idx, 'lengthTolPos', 9)" />
97 99 </template>
98 100 </uni-list-item>
99 101 <uni-list-item title="长度公差下限(mm)">
100 102 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  103 + <uni-easyinput type="text" v-model="item.lengthTolNeg" :inputBorder="false"
  104 + placeholder="请输入长度公差下限" @input="onNumberInput(idx, 'lengthTolNeg')" @blur="onNumberBlur(idx, 'lengthTolNeg', 9)" />
103 105 </template>
104 106 </uni-list-item>
105 107 <uni-list-item title="状态">
... ... @@ -109,12 +111,12 @@
109 111 </uni-list-item>
110 112 <uni-list-item title="数量">
111 113 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
  114 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 9)" />
113 115 </template>
114 116 </uni-list-item>
115 117 <uni-list-item title="单价">
116 118 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" disabled type="number" :inputBorder="false" placeholder="请输入单价" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  119 + <uni-easyinput v-model="item.unitPrice" disabled type="number" :inputBorder="false" placeholder="请输入单价" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 9)" />
118 120 </template>
119 121 </uni-list-item>
120 122 <uni-list-item title="外贸加工费">
... ... @@ -305,6 +307,27 @@ export default {
305 307 this.$set(this.items, idx, it)
306 308 if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
307 309 },
  310 + validate() {
  311 + for (let i = 0; i < this.items.length; i++) {
  312 + const it = this.items[i]
  313 + const check = (pos, neg, label) => {
  314 + if (pos !== '' && pos !== null && pos !== undefined &&
  315 + neg !== '' && neg !== null && neg !== undefined) {
  316 + if (Number(pos) <= Number(neg)) {
  317 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  318 + }
  319 + }
  320 + return null
  321 + }
  322 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  323 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  324 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  325 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  326 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  327 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  328 + }
  329 + return true
  330 + },
308 331 formatCurrency(val) {
309 332 if (val == null || val === '') return ''
310 333 const num = Number(val)
... ...
... ... @@ -21,6 +21,12 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
24 30
25 31 <uni-list-item title="订货日期">
26 32 <template v-slot:footer>
... ... @@ -39,7 +45,23 @@
39 45 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 46 </template>
41 47 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
  48 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  49 + <template v-slot:body>
  50 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  51 + </template>
  52 + <template v-slot:footer>
  53 + <view class="serial-number-row">
  54 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  55 + </view>
  56 + </template>
  57 + </uni-list-item>
  58 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  59 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  60 + <template v-slot:body>
  61 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  62 + </template>
  63 + </uni-list-item>
  64 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 65 <uni-list-item title="合计人民币金额(大写)">
44 66 <template v-slot:footer>
45 67 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +230,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 230 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 231 import ProductRel from './productRel.vue'
210 232 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
  233 +import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements, getDeptApi } from '@/api/contract'
212 234 import { getDicByCodes } from '@/utils/dic'
213 235 import { formatCurrencyToChinese } from '@/utils/common'
214 236 import { workshopQueryApi } from '@/api/devManage'
  237 +import { getArea } from '@/api/credit_manage.js'
215 238
216 239 export default {
217 240 name: 'AddContractForeignUnplan',
... ... @@ -224,6 +247,8 @@ export default {
224 247 supplierName: '',
225 248 buyer: '',
226 249 buyerName: '',
  250 + stockUpCompanyId: '',
  251 + stockUpCompanyName: '',
227 252 orderDate: '',
228 253 deliveryDate: '',
229 254 designatedConsignee: '',
... ... @@ -242,6 +267,10 @@ export default {
242 267 destinationLabel: '',
243 268 workshopIdName: '',
244 269 workshopId: '',
  270 + deptName: '',
  271 + deptId: '',
  272 + region: '',
  273 + regionName: '',
245 274 remarks: '',
246 275 component: '',
247 276 packaging: '',
... ... @@ -263,12 +292,15 @@ export default {
263 292 productList: [],
264 293 customerRemarks: [],
265 294 defaultRemark: '',
  295 + regionOptions: [],
266 296 }
267 297 },
268 298 created() {
269 299 this.loadSuppliers()
270 300 this.loadExtraOptions()
271 301 this.initCode()
  302 + this.getDept()
  303 + this.loadRegionOptions()
272 304 this.form.orderDate = this.formatDate(new Date())
273 305 this.$nextTick(() => {
274 306 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -317,6 +349,24 @@ export default {
317 349 },
318 350 },
319 351 methods: {
  352 + async loadRegionOptions() {
  353 + try {
  354 + const res = await getArea()
  355 + const list = res.data || []
  356 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  357 + } catch (e) {
  358 + this.regionOptions = []
  359 + }
  360 + },
  361 + // 查询当前人所在办事处
  362 + getDept() {
  363 + getDeptApi().then(res => {
  364 + if (res.code === 200) {
  365 + this.form.deptName = res.data.name || ''
  366 + this.form.deptId = res.data.id || ''
  367 + }
  368 + })
  369 + },
320 370 getHistory() {
321 371 console.log('this.productLineList', this.productLineList[0].productId)
322 372 if (!this.productLineList.length || !this.productLineList[0].productId) {
... ... @@ -404,7 +454,7 @@ export default {
404 454 },
405 455 displayLabel(field) {
406 456 const m = this.form
407   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂' }
  457 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
408 458 const val = m[field]
409 459 return val ? String(val) : map[field]
410 460 },
... ... @@ -449,6 +499,8 @@ export default {
449 499 setSheet('单价中是否已包含运费', this.yesNoList)
450 500 } else if (field === 'historyRemarks') {
451 501 setSheet('历史备注', this.customerRemarks)
  502 + }else if (field === 'region') {
  503 + setSheet('区域', this.regionOptions)
452 504 }
453 505 },
454 506 onSheetConfirm({ value, label }) {
... ... @@ -467,6 +519,8 @@ export default {
467 519 let config = {}
468 520 if (fieldKey === 'buyer') {
469 521 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  522 + } else if (fieldKey === 'stockUpCompanyId') {
  523 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
470 524 }
471 525 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
472 526 this.sheet.visible = false
... ... @@ -477,7 +531,17 @@ export default {
477 531 const _fieldKey = this.relate.fieldKey
478 532 const first = (items && items.length > 0) ? items[0] : null
479 533 this.form[_fieldKey] = (first && first.id) ? first.id : ''
480   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  534 +
  535 + if (_fieldKey === 'stockUpCompanyId') {
  536 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  537 + } else {
  538 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  539 + }
  540 +
  541 + if (_fieldKey === 'buyer') {
  542 + this.form.stockUpCompanyId = (first && first.id) ? first.id : ''
  543 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  544 + }
481 545 },
482 546 onRadioSelect(field, nameField, opt) {
483 547 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -489,6 +553,7 @@ export default {
489 553 }
490 554 },
491 555 async onSubmit() {
  556 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return
492 557 if (!this.validateRequired()) return
493 558 const confirmRes = await new Promise(resolve => {
494 559 uni.showModal({ title: '提示', content: '确定新增经销未锁规合同吗?', confirmText: '确定', cancelText: '取消', success: resolve })
... ... @@ -533,9 +598,11 @@ export default {
533 598 { key: 'code', label: '编号' },
534 599 { key: 'supplier', label: '供方' },
535 600 { key: 'buyer', label: '需方' },
  601 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
536 602 { key: 'orderDate', label: '订货日期' },
537 603 { key: 'unit', label: '单位' },
538 604 { key: 'workshopId', label: '生产厂' },
  605 + { key: 'region', label: '区域' },
539 606 { key: 'specialTerms', label: '特别条款要求' },
540 607 ]
541 608 for (const it of checks) {
... ...
... ... @@ -17,11 +17,17 @@
17 17 }}</text></view>
18 18 <view class="row"><text class="label">需方</text><text class="value">{{ detail.buyerName || '-'
19 19 }}</text></view>
  20 + <view class="row"><text class="label">备货单位/人(生产标准)</text><text class="value">{{ detail.stockUpCompanyName || '-'
  21 + }}</text></view>
20 22 <view class="row"><text class="label">订货日期</text><text class="value">{{ detail.orderDate }}</text>
21 23 </view>
22 24 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
23 25 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName || '-'
24 26 }}</text></view>
  27 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  28 + }}</text></view>
  29 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  30 + }}</text></view>
25 31 </view>
26 32
27 33 <view class="section1">
... ... @@ -148,10 +154,15 @@ export default {
148 154 supplierName: '',
149 155 buyer: '',
150 156 buyerName: '',
  157 + stockUpCompanyId: '',
  158 + stockUpCompanyName: '',
151 159 orderDate: '',
152 160 unit: '',
153 161 workshopId: '',
154 162 workshopName: '',
  163 + deptName: '',
  164 + region: '',
  165 + regionName: '',
155 166 designatedConsignee: '',
156 167 specialTerms: '',
157 168 specialTermsName: '',
... ... @@ -480,6 +491,9 @@ export default {
480 491 this.detail = {
481 492 ...this.detail,
482 493 ...data,
  494 + stockUpCompanyName: data.stockUpCompanyName || '',
  495 + regionName: data.regionName || '',
  496 + deptName: data.deptName || '',
483 497 includesPackagingFeeName, includesTransportFeeName,
484 498 destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',
485 499 destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '',
... ...
... ... @@ -22,12 +22,35 @@
22 22 </template>
23 23 </uni-list-item>
24 24
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
25 32 <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
26 33 @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
27 34 <template v-slot:body>
28 35 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
29 36 </template>
30 37 </uni-list-item>
  38 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  39 + <template v-slot:body>
  40 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  41 + </template>
  42 + <template v-slot:footer>
  43 + <view class="serial-number-row">
  44 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  45 + </view>
  46 + </template>
  47 + </uni-list-item>
  48 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  49 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  50 + <template v-slot:body>
  51 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  52 + </template>
  53 + </uni-list-item>
31 54
32 55 <uni-list-item title="订货日期">
33 56 <template v-slot:footer>
... ... @@ -41,7 +64,7 @@
41 64 </template>
42 65 </uni-list-item>
43 66
44   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  67 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 68
46 69 <uni-list-item title="合计人民币金额(大写)">
47 70 <template v-slot:footer>
... ... @@ -198,6 +221,8 @@ import { getContractApi, updateContractApi } from '@/api/contract'
198 221 import { getDicByCodes } from '@/utils/dic'
199 222 import { formatCurrencyToChinese } from '@/utils/common'
200 223 import { workshopQueryApi } from '@/api/devManage'
  224 +import { getArea } from '@/api/credit_manage.js'
  225 +
201 226 export default {
202 227 name: 'ModifyContractForeignUnplan',
203 228 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -211,8 +236,14 @@ export default {
211 236 supplierName: '',
212 237 buyer: '',
213 238 buyerName: '',
  239 + stockUpCompanyId: '',
  240 + stockUpCompanyName: '',
214 241 workshopId: '',
215 242 workshopName: '',
  243 + region: '',
  244 + regionName: '',
  245 + deptName: '',
  246 + deptId: '',
216 247 orderDate: '',
217 248 deliveryDate: '',
218 249 designatedConsignee: '',
... ... @@ -253,7 +284,8 @@ export default {
253 284 totalAmountIncludingTax: 0,
254 285 productLineList: [],
255 286 newProductLineList: [],
256   - productList: []
  287 + productList: [],
  288 + regionOptions: []
257 289 }
258 290 },
259 291 onLoad(query) {
... ... @@ -262,6 +294,7 @@ export default {
262 294 created() {
263 295 this.loadSuppliers()
264 296 this.loadExtraOptions()
  297 + this.loadRegionOptions()
265 298 this.loadDetail()
266 299 this.$nextTick(() => {
267 300 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -270,6 +303,15 @@ export default {
270 303 })
271 304 },
272 305 methods: {
  306 + async loadRegionOptions() {
  307 + try {
  308 + const res = await getArea()
  309 + const list = res.data || []
  310 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  311 + } catch (e) {
  312 + this.regionOptions = []
  313 + }
  314 + },
273 315 async loadDetail() {
274 316 if (!this.id) return
275 317 try {
... ... @@ -286,6 +328,8 @@ export default {
286 328 supplierName: m.supplierName || '',
287 329 buyer: m.buyer || (m.customer && m.customer.id) || '',
288 330 buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  331 + stockUpCompanyId: m.stockUpCompanyId || '',
  332 + stockUpCompanyName: m.stockUpCompanyName || '',
289 333 orderDate: m.orderDate || '',
290 334 designatedConsignee: m.designatedConsignee || '',
291 335 specialTerms: m.specialTerms || '',
... ... @@ -315,6 +359,10 @@ export default {
315 359 packaging: m.packaging || '',
316 360 workshopId: m.workshopId || '',
317 361 workshopName: m.workshopName || '',
  362 + region: m.region || '',
  363 + regionName: m.regionName || '',
  364 + deptName: m.deptName || '',
  365 + deptId: m.deptId || '',
318 366 }
319 367 const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
320 368 this.productLineList = lines
... ... @@ -370,7 +418,7 @@ export default {
370 418 },
371 419 displayLabel(field) {
372 420 const m = this.form
373   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂' }
  421 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
374 422 const val = m[field]
375 423 return val ? String(val) : map[field]
376 424 },
... ... @@ -399,6 +447,8 @@ export default {
399 447 setSheet('单价中是否已包含包装费', this.yesNoList)
400 448 } else if (field === 'includesTransportFee') {
401 449 setSheet('单价中是否已包含运费', this.yesNoList)
  450 + } else if (field === 'region') {
  451 + setSheet('区域', this.regionOptions)
402 452 }
403 453 },
404 454 onSheetConfirm({ value, label }) {
... ... @@ -412,6 +462,8 @@ export default {
412 462 let config = {}
413 463 if (fieldKey === 'buyer') {
414 464 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  465 + } else if (fieldKey === 'stockUpCompanyId') {
  466 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
415 467 }
416 468 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
417 469 this.sheet.visible = false
... ... @@ -422,7 +474,12 @@ export default {
422 474 const _fieldKey = this.relate.fieldKey
423 475 const first = (items && items.length > 0) ? items[0] : null
424 476 this.form[_fieldKey] = (first && first.id) ? first.id : ''
425   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  477 +
  478 + if (_fieldKey === 'stockUpCompanyId') {
  479 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  480 + } else {
  481 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  482 + }
426 483 },
427 484 onRadioSelect(field, nameField, opt) {
428 485 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -438,9 +495,11 @@ export default {
438 495 { key: 'code', label: '编号' },
439 496 { key: 'supplier', label: '供方' },
440 497 { key: 'buyer', label: '需方' },
  498 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
441 499 { key: 'orderDate', label: '订货日期' },
442 500 { key: 'unit', label: '单位' },
443 501 { key: 'workshopId', label: '生产厂' },
  502 + { key: 'region', label: '区域' },
444 503 { key: 'specialTerms', label: '特别条款要求' },
445 504 ]
446 505 for (const it of checks) {
... ... @@ -470,8 +529,8 @@ export default {
470 529 return true
471 530 },
472 531 async onSubmit() {
473   - console.log('onSubmit__payload', payload)
474 532 if (!this.validateRequired()) return
  533 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return
475 534 const confirmRes = await new Promise(resolve => {
476 535 uni.showModal({ title: '提示', content: '确定保存当前经销未锁规合同吗?', confirmText: '确定', cancelText: '取消', success: resolve })
477 536 })
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度(mm)">
57 57 <template v-slot:footer>
58   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差上限(mm)">
62 62 <template v-slot:footer>
63 63 <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  64 + placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 9)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差下限(mm)">
68 68 <template v-slot:footer>
69 69 <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  70 + placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 9)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度(mm)">
74 74 <template v-slot:footer>
75   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差上限(mm)">
79 79 <template v-slot:footer>
80   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  80 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 9)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差下限(mm)">
84 84 <template v-slot:footer>
85   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  85 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 9)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度(mm)">
89 89 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差上限(mm)">
94 94 <template v-slot:footer>
95 95 <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  96 + placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 9)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差下限(mm)">
100 100 <template v-slot:footer>
101 101 <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  102 + placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 9)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 9)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 9)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="外贸加工费">
... ... @@ -286,6 +286,73 @@ export default {
286 286 const m = Math.pow(10, digits)
287 287 return Math.round(n * m) / m
288 288 },
  289 + onNumberInput(idx, field) {
  290 + const it = this.items[idx]
  291 + if (!it) return
  292 + // 允许负号和小数点
  293 + let v = String(it[field] != null ? it[field] : '')
  294 + // 先只保留数字、小数点、负号
  295 + v = v.replace(/[^0-9.-]/g, '')
  296 + // 处理负号:只有第一个位置可以是负号,如果后面出现负号则移除
  297 + if (v.lastIndexOf('-') > 0) {
  298 + const hasMinusAtStart = v.startsWith('-')
  299 + v = v.replace(/-/g, '')
  300 + if (hasMinusAtStart) v = '-' + v
  301 + }
  302 + // 处理小数点:只保留第一个小数点
  303 + if ((v.match(/\./g) || []).length > 1) {
  304 + const firstDotIndex = v.indexOf('.')
  305 + v = v.substring(0, firstDotIndex + 1) + v.substring(firstDotIndex + 1).replace(/\./g, '')
  306 + }
  307 + // 处理特殊情况:.5 -> 0.5, -.5 -> -0.5
  308 + if (v.startsWith('.')) v = '0' + v
  309 + if (v.startsWith('-.')) v = '-0' + v.substring(1)
  310 +
  311 + it[field] = v
  312 + this.$set(this.items, idx, it)
  313 + },
  314 + onNumberBlur(idx, field, digits = 2) {
  315 + const it = this.items[idx]
  316 + if (!it) return
  317 + let v = it[field]
  318 + if (v === '' || v === '-' || v === null || v === undefined) {
  319 + // 如果为空或只有一个负号,不处理或置空,看需求,这里保持原值或空
  320 + } else {
  321 + // 转为数字并保留小数位
  322 + const num = Number(v)
  323 + if (!isNaN(num)) {
  324 + it[field] = this.round(num, digits)
  325 + } else {
  326 + it[field] = ''
  327 + }
  328 + }
  329 + this.$set(this.items, idx, it)
  330 + },
  331 + validate() {
  332 + for (let i = 0; i < this.items.length; i++) {
  333 + const it = this.items[i]
  334 + const check = (pos, neg, label) => {
  335 + // 只有当上限和下限都有值时才校验
  336 + if (pos !== '' && pos !== null && pos !== undefined &&
  337 + neg !== '' && neg !== null && neg !== undefined) {
  338 + if (Number(pos) <= Number(neg)) {
  339 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  340 + }
  341 + }
  342 + return null
  343 + }
  344 +
  345 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  346 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  347 +
  348 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  349 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  350 +
  351 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  352 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  353 + }
  354 + return true
  355 + },
289 356 onNonNegativeBlur(idx, field, digits) {
290 357 const it = this.items[idx]
291 358 if (!it) return
... ...
... ... @@ -21,6 +21,12 @@
21 21 <view class="item-title"><text class="required">*</text><text>定作方</text></view>
22 22 </template>
23 23 </uni-list-item>
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
24 30
25 31 <uni-list-item title="订货日期">
26 32 <template v-slot:footer>
... ... @@ -39,7 +45,23 @@
39 45 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 46 </template>
41 47 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" @change="onProductsChange" :options="productList" :rawToProdRatioList="rawToProdRatioList" />
  48 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  49 + <template v-slot:body>
  50 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  51 + </template>
  52 + <template v-slot:footer>
  53 + <view class="serial-number-row">
  54 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  55 + </view>
  56 + </template>
  57 + </uni-list-item>
  58 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  59 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  60 + <template v-slot:body>
  61 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  62 + </template>
  63 + </uni-list-item>
  64 + <ProductRel ref="productRel" mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" @change="onProductsChange" :options="productList" :rawToProdRatioList="rawToProdRatioList" />
43 65 <uni-list-item title="合计人民币金额(大写)">
44 66 <template v-slot:footer>
45 67 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +230,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 230 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 231 import ProductRel from './productRel.vue'
210 232 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
  233 +import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements, getDeptApi } from '@/api/contract'
212 234 import { getDicByCodes } from '@/utils/dic'
213 235 import { formatCurrencyToChinese } from '@/utils/common'
214 236 import { workshopQueryApi } from '@/api/devManage'
  237 +import { getArea } from '@/api/credit_manage.js'
215 238
216 239 export default {
217 240 name: 'AddContractProcess',
... ... @@ -224,6 +247,8 @@ export default {
224 247 supplierName: '',
225 248 buyer: '',
226 249 buyerName: '',
  250 + stockUpCompanyId: '',
  251 + stockUpCompanyName: '',
227 252 orderDate: '',
228 253 deliveryDate: '',
229 254 designatedConsignee: '',
... ... @@ -242,6 +267,10 @@ export default {
242 267 destinationLabel: '',
243 268 workshopIdName: '',
244 269 workshopId: '',
  270 + deptName: '',
  271 + deptId: '',
  272 + region: '',
  273 + regionName: '',
245 274 remarks: '',
246 275 component: '',
247 276 packaging: '',
... ... @@ -261,15 +290,18 @@ export default {
261 290 totalAmountIncludingTax: 0,
262 291 productLineList: [],
263 292 productList: [],
264   - rawToProdRatioList: [],
265 293 customerRemarks: [],
266 294 defaultRemark: '',
  295 + regionOptions: [],
  296 + rawToProdRatioList: [],
267 297 }
268 298 },
269 299 created() {
270 300 this.loadSuppliers()
271 301 this.loadExtraOptions()
272 302 this.initCode()
  303 + this.getDept()
  304 + this.loadRegionOptions()
273 305 this.form.orderDate = this.formatDate(new Date())
274 306 this.$nextTick(() => {
275 307 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -318,6 +350,24 @@ export default {
318 350 },
319 351 },
320 352 methods: {
  353 + async loadRegionOptions() {
  354 + try {
  355 + const res = await getArea()
  356 + const list = res.data || []
  357 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  358 + } catch (e) {
  359 + this.regionOptions = []
  360 + }
  361 + },
  362 + // 查询当前人所在办事处
  363 + getDept() {
  364 + getDeptApi().then(res => {
  365 + if (res.code === 200) {
  366 + this.form.deptName = res.data.name || ''
  367 + this.form.deptId = res.data.id || ''
  368 + }
  369 + })
  370 + },
321 371 getHistory() {
322 372 console.log('this.productLineList', this.productLineList[0].rawProductId)
323 373 if (!this.productLineList.length || !this.productLineList[0].rawProductId) {
... ... @@ -408,7 +458,7 @@ export default {
408 458 },
409 459 displayLabel(field) {
410 460 const m = this.form
411   - const map = { supplierName: '请选择承揽方', buyerName: '请选择定作方', workshopIdName: '请选择生产厂' }
  461 + const map = { supplierName: '请选择承揽方', buyerName: '请选择定作方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
412 462 const val = m[field]
413 463 return val ? String(val) : map[field]
414 464 },
... ... @@ -453,6 +503,8 @@ export default {
453 503 setSheet('单价中是否已包含运费', this.yesNoList)
454 504 } else if (field === 'historyRemarks') {
455 505 setSheet('历史备注', this.customerRemarks)
  506 + }else if (field === 'region') {
  507 + setSheet('区域', this.regionOptions)
456 508 }
457 509 },
458 510 onSheetConfirm({ value, label }) {
... ... @@ -471,6 +523,8 @@ export default {
471 523 let config = {}
472 524 if (fieldKey === 'buyer') {
473 525 config = { title: '定作方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  526 + } else if (fieldKey === 'stockUpCompanyId') {
  527 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
474 528 }
475 529 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
476 530 this.sheet.visible = false
... ... @@ -481,7 +535,17 @@ export default {
481 535 const _fieldKey = this.relate.fieldKey
482 536 const first = (items && items.length > 0) ? items[0] : null
483 537 this.form[_fieldKey] = (first && first.id) ? first.id : ''
484   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  538 +
  539 + if (_fieldKey === 'stockUpCompanyId') {
  540 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  541 + } else {
  542 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  543 + }
  544 +
  545 + if (_fieldKey === 'buyer') {
  546 + this.form.stockUpCompanyId = (first && first.id) ? first.id : ''
  547 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  548 + }
485 549 },
486 550 onRadioSelect(field, nameField, opt) {
487 551 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -542,9 +606,11 @@ export default {
542 606 { key: 'code', label: '编号' },
543 607 { key: 'supplier', label: '承揽方' },
544 608 { key: 'buyer', label: '定作方' },
  609 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
545 610 { key: 'orderDate', label: '订货日期' },
546   - { key: 'workshopId', label: '生产厂' },
547 611 { key: 'unit', label: '单位' },
  612 + { key: 'workshopId', label: '生产厂' },
  613 + { key: 'region', label: '区域' },
548 614 { key: 'specialTerms', label: '特别条款要求' },
549 615 ]
550 616 for (const it of checks) {
... ... @@ -552,6 +618,7 @@ export default {
552 618 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
553 619 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
554 620 }
  621 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
555 622 const list = Array.isArray(this.productLineList) ? this.productLineList : []
556 623 if (list.length === 0) {
557 624 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -10,11 +10,17 @@ statusStyl<template>
10 10 }}</text></view>
11 11 <view class="row"><text class="label">定作方</text><text class="value">{{ detail.buyerName || '-'
12 12 }}</text></view>
  13 + <view class="row"><text class="label">备货单位/人(生产标准)</text><text class="value">{{ detail.stockUpCompanyName || '-'
  14 + }}</text></view>
13 15 <view class="row"><text class="label">订货日期</text><text class="value">{{ detail.orderDate }}</text>
14 16 </view>
15 17 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
16 18 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName || '-'
17   - }}</text></view>
  19 + }}</text></view>
  20 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  21 + }}</text></view>
  22 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  23 + }}</text></view>
18 24 </view>
19 25
20 26 <view class="section1">
... ... @@ -130,10 +136,15 @@ export default {
130 136 supplierName: '',
131 137 buyer: '',
132 138 buyerName: '',
  139 + stockUpCompanyId: '',
  140 + stockUpCompanyName: '',
133 141 orderDate: '',
134 142 unit: '',
135 143 workshopId: '',
136 144 workshopName: '',
  145 + deptName: '',
  146 + region: '',
  147 + regionName: '',
137 148 designatedConsignee: '',
138 149 specialTerms: '',
139 150 specialTermsName: '',
... ... @@ -361,9 +372,12 @@ export default {
361 372 const data = res && res.data ? res.data : {}
362 373 const includesPackagingFeeName = data.includesPackagingFeeName || (data.includesPackagingFee ? '是' : '否')
363 374 const includesTransportFeeName = data.includesTransportFeeName || (data.includesTransportFee ? '是' : '否')
364   - this.detail = {
365   - ...this.detail,
366   - ...data,
  375 + this.detail = {
  376 + ...this.detail,
  377 + ...data,
  378 + stockUpCompanyName: data.stockUpCompanyName || '',
  379 + regionName: data.regionName || '',
  380 + deptName: data.deptName || '',
367 381 includesPackagingFeeName, includesTransportFeeName,
368 382 destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',
369 383 destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '',
... ...
... ... @@ -199,6 +199,8 @@ import { getContractApi, updateContractApi } from '@/api/contract'
199 199 import { getDicByCodes } from '@/utils/dic'
200 200 import { formatCurrencyToChinese } from '@/utils/common'
201 201 import { workshopQueryApi } from '@/api/devManage'
  202 +import { getArea } from '@/api/credit_manage.js'
  203 +
202 204 export default {
203 205 name: 'ModifyContractProcess',
204 206 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -212,8 +214,14 @@ export default {
212 214 supplierName: '',
213 215 buyer: '',
214 216 buyerName: '',
  217 + stockUpCompanyId: '',
  218 + stockUpCompanyName: '',
215 219 workshopId: '',
216 220 workshopName: '',
  221 + region: '',
  222 + regionName: '',
  223 + deptName: '',
  224 + deptId: '',
217 225 orderDate: '',
218 226 deliveryDate: '',
219 227 designatedConsignee: '',
... ... @@ -255,6 +263,7 @@ export default {
255 263 productLineList: [],
256 264 newProductLineList: [],
257 265 productList: [],
  266 + regionOptions: [],
258 267 rawToProdRatioList: [],
259 268 }
260 269 },
... ... @@ -264,6 +273,7 @@ export default {
264 273 created() {
265 274 this.loadSuppliers()
266 275 this.loadExtraOptions()
  276 + this.loadRegionOptions()
267 277 this.loadDetail()
268 278 this.$nextTick(() => {
269 279 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -272,6 +282,15 @@ export default {
272 282 })
273 283 },
274 284 methods: {
  285 + async loadRegionOptions() {
  286 + try {
  287 + const res = await getArea()
  288 + const list = res.data || []
  289 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  290 + } catch (e) {
  291 + this.regionOptions = []
  292 + }
  293 + },
275 294 async loadDetail() {
276 295 if (!this.id) return
277 296 try {
... ... @@ -288,6 +307,8 @@ export default {
288 307 supplierName: m.supplierName || '',
289 308 buyer: m.buyer || (m.customer && m.customer.id) || '',
290 309 buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  310 + stockUpCompanyId: m.stockUpCompanyId || '',
  311 + stockUpCompanyName: m.stockUpCompanyName || '',
291 312 orderDate: m.orderDate || '',
292 313 designatedConsignee: m.designatedConsignee || '',
293 314 specialTerms: m.specialTerms || '',
... ... @@ -317,6 +338,10 @@ export default {
317 338 packaging: m.packaging || '',
318 339 workshopId: m.workshopId || '',
319 340 workshopName: m.workshopName || '',
  341 + region: m.region || '',
  342 + regionName: m.regionName || '',
  343 + deptName: m.deptName || '',
  344 + deptId: m.deptId || '',
320 345 }
321 346 const lines = Array.isArray(m.contractStdProcessingLineList) ? m.contractStdProcessingLineList : []
322 347 this.productLineList = lines
... ... @@ -453,6 +478,7 @@ export default {
453 478 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
454 479 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
455 480 }
  481 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
456 482 const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
457 483 if (list.length === 0) {
458 484 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -87,61 +87,61 @@
87 87
88 88 <uni-list-item title="厚度(mm)">
89 89 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  90 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="厚度公差上限(mm)">
94 94 <template v-slot:footer>
95   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
96   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  95 + <uni-easyinput type="text" v-model="item.thicknessTolPos" :inputBorder="false"
  96 + placeholder="请输入厚度公差上限" @input="onNumberInput(idx, 'thicknessTolPos')" @blur="onNumberBlur(idx, 'thicknessTolPos', 9)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="厚度公差下限(mm)">
100 100 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
102   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  101 + <uni-easyinput type="text" v-model="item.thicknessTolNeg" :inputBorder="false"
  102 + placeholder="请输入厚度公差下限" @input="onNumberInput(idx, 'thicknessTolNeg')" @blur="onNumberBlur(idx, 'thicknessTolNeg', 9)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="宽度(mm)">
106 106 <template v-slot:footer>
107   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  107 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
108 108 </template>
109 109 </uni-list-item>
110 110 <uni-list-item title="宽度公差上限(mm)">
111 111 <template v-slot:footer>
112   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  112 + <uni-easyinput type="text" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNumberInput(idx, 'widthTolPos')" @blur="onNumberBlur(idx, 'widthTolPos', 9)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="宽度公差下限(mm)">
116 116 <template v-slot:footer>
117   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  117 + <uni-easyinput type="text" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNumberInput(idx, 'widthTolNeg')" @blur="onNumberBlur(idx, 'widthTolNeg', 9)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="长度(mm)">
121 121 <template v-slot:footer>
122   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  122 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
123 123 </template>
124 124 </uni-list-item>
125 125 <uni-list-item title="长度公差上限(mm)">
126 126 <template v-slot:footer>
127   - <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
128   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  127 + <uni-easyinput type="text" v-model="item.lengthTolPos" :inputBorder="false"
  128 + placeholder="请输入长度公差上限" @input="onNumberInput(idx, 'lengthTolPos')" @blur="onNumberBlur(idx, 'lengthTolPos', 9)" />
129 129 </template>
130 130 </uni-list-item>
131 131 <uni-list-item title="长度公差下限(mm)">
132 132 <template v-slot:footer>
133   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
134   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  133 + <uni-easyinput type="text" v-model="item.lengthTolNeg" :inputBorder="false"
  134 + placeholder="请输入长度公差下限" @input="onNumberInput(idx, 'lengthTolNeg')" @blur="onNumberBlur(idx, 'lengthTolNeg', 9)" />
135 135 </template>
136 136 </uni-list-item>
137 137 <uni-list-item title="定作物数量">
138 138 <template v-slot:footer>
139   - <uni-easyinput v-model="item.productQuantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'productQuantity')" @blur="onNonNegativeBlur(idx, 'productQuantity', 2)" />
  139 + <uni-easyinput v-model="item.productQuantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'productQuantity')" @blur="onNonNegativeBlur(idx, 'productQuantity', 9)" />
140 140 </template>
141 141 </uni-list-item>
142 142 <uni-list-item title="加工费单价">
143 143 <template v-slot:footer>
144   - <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  144 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 9)" />
145 145 </template>
146 146 </uni-list-item>
147 147 <uni-list-item title="不含税金额">
... ... @@ -295,6 +295,45 @@ export default {
295 295 defaultItem() {
296 296 return { productId:'', productName:'', productGrade:'', productStatus:'', rawProductId: '', rawProductName: '', rawProductGrade: '', industry: '',materialProductRatioRemarks:'', supplyTime: '存料加工', materialProductRatio: '', rawToProdRatioName: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', productQuantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
297 297 },
  298 + onNumberInput(idx, field) {
  299 + const it = this.items[idx]
  300 + if (!it) return
  301 + let v = String(it[field] != null ? it[field] : '')
  302 + v = v.replace(/[^0-9.-]/g, '')
  303 + if ((v.match(/-/g) || []).length > 1) {
  304 + const first = v.indexOf('-') === 0 ? '-' : ''
  305 + v = first + v.replace(/-/g, '')
  306 + } else if (v.indexOf('-') > 0) {
  307 + v = v.replace(/-/g, '')
  308 + }
  309 + if ((v.match(/\./g) || []).length > 1) {
  310 + const parts = v.split('.')
  311 + v = parts[0] + '.' + parts.slice(1).join('')
  312 + }
  313 + it[field] = v
  314 + this.$set(this.items, idx, it)
  315 + },
  316 + validate() {
  317 + for (let i = 0; i < this.items.length; i++) {
  318 + const it = this.items[i]
  319 + const check = (pos, neg, label) => {
  320 + if (pos !== '' && pos !== null && pos !== undefined &&
  321 + neg !== '' && neg !== null && neg !== undefined) {
  322 + if (Number(pos) <= Number(neg)) {
  323 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  324 + }
  325 + }
  326 + return null
  327 + }
  328 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  329 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  330 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  331 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  332 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  333 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  334 + }
  335 + return true
  336 + },
298 337 onNonNegativeInput(idx, field) {
299 338 const it = this.items[idx]
300 339 if (!it) return
... ...
... ... @@ -21,6 +21,13 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
  30 +
24 31
25 32 <uni-list-item title="订货日期">
26 33 <template v-slot:footer>
... ... @@ -39,7 +46,18 @@
39 46 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 47 </template>
41 48 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" @change="onProductsChange" :options="productList" />
  49 + <uni-list-item title="办事处">
  50 + <template v-slot:footer>
  51 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  52 + </template>
  53 + </uni-list-item>
  54 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  55 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  56 + <template v-slot:body>
  57 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  58 + </template>
  59 + </uni-list-item>
  60 + <ProductRel ref="productRel" mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
43 61 <uni-list-item title="合计人民币金额(大写)">
44 62 <template v-slot:footer>
45 63 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +226,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 226 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 227 import ProductRel from './productRel.vue'
210 228 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
  229 +import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements, getDeptApi } from '@/api/contract'
212 230 import { getDicByCodes } from '@/utils/dic'
213 231 import { formatCurrencyToChinese } from '@/utils/common'
214 232 import { workshopQueryApi } from '@/api/devManage'
  233 +import { getArea } from '@/api/credit_manage.js'
215 234
216 235 export default {
217 236 name: 'AddContractRetail',
... ... @@ -224,6 +243,8 @@ export default {
224 243 supplierName: '',
225 244 buyer: '',
226 245 buyerName: '',
  246 + stockUpCompanyId: '',
  247 + stockUpCompanyName: '',
227 248 orderDate: '',
228 249 deliveryDate: '',
229 250 designatedConsignee: '',
... ... @@ -242,6 +263,10 @@ export default {
242 263 destinationLabel: '',
243 264 workshopIdName: '',
244 265 workshopId: '',
  266 + deptName: '',
  267 + deptId: '',
  268 + region: '',
  269 + regionName: '',
245 270 remarks: '',
246 271 component: '',
247 272 packaging: '',
... ... @@ -263,12 +288,15 @@ export default {
263 288 productList: [],
264 289 customerRemarks: [],
265 290 defaultRemark: '',
  291 + regionOptions: [],
266 292 }
267 293 },
268 294 created() {
269 295 this.loadSuppliers()
270 296 this.loadExtraOptions()
271 297 this.initCode()
  298 + this.getDept()
  299 + this.loadRegionOptions()
272 300 this.form.orderDate = this.formatDate(new Date())
273 301 this.$nextTick(() => {
274 302 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -318,6 +346,24 @@ export default {
318 346 },
319 347 },
320 348 methods: {
  349 + async loadRegionOptions() {
  350 + try {
  351 + const res = await getArea()
  352 + const list = res.data || []
  353 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  354 + } catch (e) {
  355 + this.regionOptions = []
  356 + }
  357 + },
  358 + // 查询当前人所在办事处
  359 + getDept() {
  360 + getDeptApi().then(res => {
  361 + if (res.code === 200) {
  362 + this.form.deptName = res.data.name || ''
  363 + this.form.deptId = res.data.id || ''
  364 + }
  365 + })
  366 + },
321 367 getHistory() {
322 368 console.log('this.productLineList', this.productLineList[0].productId)
323 369 if (!this.productLineList.length || !this.productLineList[0].productId) {
... ... @@ -405,7 +451,7 @@ export default {
405 451 },
406 452 displayLabel(field) {
407 453 const m = this.form
408   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂' }
  454 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
409 455 const val = m[field]
410 456 return val ? String(val) : map[field]
411 457 },
... ... @@ -450,6 +496,8 @@ export default {
450 496 setSheet('单价中是否已包含运费', this.yesNoList)
451 497 } else if (field === 'historyRemarks') {
452 498 setSheet('历史备注', this.customerRemarks)
  499 + }else if (field === 'region') {
  500 + setSheet('区域', this.regionOptions)
453 501 }
454 502 },
455 503 onSheetConfirm({ value, label }) {
... ... @@ -468,6 +516,8 @@ export default {
468 516 let config = {}
469 517 if (fieldKey === 'buyer') {
470 518 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  519 + } else if (fieldKey === 'stockUpCompanyId') {
  520 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
471 521 }
472 522 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
473 523 this.sheet.visible = false
... ... @@ -478,7 +528,17 @@ export default {
478 528 const _fieldKey = this.relate.fieldKey
479 529 const first = (items && items.length > 0) ? items[0] : null
480 530 this.form[_fieldKey] = (first && first.id) ? first.id : ''
481   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  531 +
  532 + if (_fieldKey === 'stockUpCompanyId') {
  533 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  534 + } else {
  535 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  536 + }
  537 +
  538 + if (_fieldKey === 'buyer') {
  539 + this.form.stockUpCompanyId = (first && first.id) ? first.id : ''
  540 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  541 + }
482 542 },
483 543 onRadioSelect(field, nameField, opt) {
484 544 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -534,9 +594,11 @@ export default {
534 594 { key: 'code', label: '编号' },
535 595 { key: 'supplier', label: '供方' },
536 596 { key: 'buyer', label: '需方' },
  597 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
537 598 { key: 'orderDate', label: '订货日期' },
538 599 { key: 'unit', label: '单位' },
539 600 { key: 'workshopId', label: '生产厂' },
  601 + { key: 'region', label: '区域' },
540 602 { key: 'specialTerms', label: '特别条款要求' },
541 603 ]
542 604 for (const it of checks) {
... ... @@ -544,6 +606,7 @@ export default {
544 606 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
545 607 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
546 608 }
  609 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
547 610 const list = Array.isArray(this.productLineList) ? this.productLineList : []
548 611 if (list.length === 0) {
549 612 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -10,11 +10,17 @@
10 10 '-'}}</text></view>
11 11 <view class="row"><text class="label">需方</text><text class="value">{{ detail.buyerName ||
12 12 '-'}}</text></view>
  13 + <view class="row"><text class="label">备货单位/人(生产标准)</text><text class="value">{{ detail.stockUpCompanyName || '-'
  14 + }}</text></view>
13 15 <view class="row"><text class="label">订货日期</text><text class="value">{{ detail.orderDate }}</text>
14 16 </view>
15 17 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
16 18 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName ||
17 19 '-'}}</text></view>
  20 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  21 + }}</text></view>
  22 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  23 + }}</text></view>
18 24 </view>
19 25
20 26 <view class="section1">
... ... @@ -156,7 +162,11 @@ export default {
156 162 tolerance: '',
157 163 performance: '',
158 164 component: '',
159   - packaging: ''
  165 + packaging: '',
  166 + stockUpCompanyId: '',
  167 + stockUpCompanyName: '',
  168 + region: '',
  169 + regionName: '',
160 170 },
161 171 productList: [],
162 172 fileInfo: { id: '', name: '' },
... ...
... ... @@ -21,7 +21,7 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
24   -
  24 +
25 25 <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
26 26 @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
27 27 <template v-slot:body>
... ... @@ -40,8 +40,23 @@
40 40 <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
41 41 </template>
42 42 </uni-list-item>
43   -
44   - <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  43 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  44 + <template v-slot:body>
  45 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  46 + </template>
  47 + <template v-slot:footer>
  48 + <view class="serial-number-row">
  49 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  50 + </view>
  51 + </template>
  52 + </uni-list-item>
  53 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  54 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  55 + <template v-slot:body>
  56 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  57 + </template>
  58 + </uni-list-item>
  59 + <ProductRel ref="productRel" mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 60
46 61 <uni-list-item title="合计人民币金额(大写)">
47 62 <template v-slot:footer>
... ... @@ -199,6 +214,8 @@ import { getContractApi, updateContractApi } from '@/api/contract'
199 214 import { getDicByCodes } from '@/utils/dic'
200 215 import { formatCurrencyToChinese } from '@/utils/common'
201 216 import { workshopQueryApi } from '@/api/devManage'
  217 +import { getArea } from '@/api/credit_manage.js'
  218 +
202 219 export default {
203 220 name: 'ModifyContractRetail',
204 221 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -212,6 +229,12 @@ export default {
212 229 supplierName: '',
213 230 buyer: '',
214 231 buyerName: '',
  232 + stockUpCompanyId: '',
  233 + stockUpCompanyName: '',
  234 + region: '',
  235 + regionName: '',
  236 + deptName: '',
  237 + deptId: '',
215 238 workshopId: '',
216 239 workshopName: '',
217 240 orderDate: '',
... ... @@ -254,7 +277,8 @@ export default {
254 277 totalAmountIncludingTax: 0,
255 278 productLineList: [],
256 279 newProductLineList: [],
257   - productList: []
  280 + productList: [],
  281 + regionOptions: []
258 282 }
259 283 },
260 284 onLoad(query) {
... ... @@ -263,6 +287,7 @@ export default {
263 287 created() {
264 288 this.loadSuppliers()
265 289 this.loadExtraOptions()
  290 + this.loadRegionOptions()
266 291 this.loadDetail()
267 292 this.$nextTick(() => {
268 293 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -271,6 +296,15 @@ export default {
271 296 })
272 297 },
273 298 methods: {
  299 + async loadRegionOptions() {
  300 + try {
  301 + const res = await getArea()
  302 + const list = res.data || []
  303 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  304 + } catch (e) {
  305 + this.regionOptions = []
  306 + }
  307 + },
274 308 async loadDetail() {
275 309 if (!this.id) return
276 310 try {
... ... @@ -316,6 +350,12 @@ export default {
316 350 packaging: m.packaging || '',
317 351 workshopId: m.workshopId || '',
318 352 workshopName: m.workshopName || '',
  353 + stockUpCompanyId: m.stockUpCompanyId || '',
  354 + stockUpCompanyName: m.stockUpCompanyName || '',
  355 + region: m.region || '',
  356 + regionName: m.regionName || '',
  357 + deptName: m.deptName || '',
  358 + deptId: m.deptId || '',
319 359 }
320 360 const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
321 361 this.productLineList = lines
... ... @@ -371,7 +411,7 @@ export default {
371 411 },
372 412 displayLabel(field) {
373 413 const m = this.form
374   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂' }
  414 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
375 415 const val = m[field]
376 416 return val ? String(val) : map[field]
377 417 },
... ... @@ -400,6 +440,8 @@ export default {
400 440 setSheet('单价中是否已包含包装费', this.yesNoList)
401 441 } else if (field === 'includesTransportFee') {
402 442 setSheet('单价中是否已包含运费', this.yesNoList)
  443 + } else if (field === 'region') {
  444 + setSheet('区域', this.regionOptions)
403 445 }
404 446 },
405 447 onSheetConfirm({ value, label }) {
... ... @@ -413,6 +455,8 @@ export default {
413 455 let config = {}
414 456 if (fieldKey === 'buyer') {
415 457 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  458 + } else if (fieldKey === 'stockUpCompanyId') {
  459 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
416 460 }
417 461 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
418 462 this.sheet.visible = false
... ... @@ -423,7 +467,11 @@ export default {
423 467 const _fieldKey = this.relate.fieldKey
424 468 const first = (items && items.length > 0) ? items[0] : null
425 469 this.form[_fieldKey] = (first && first.id) ? first.id : ''
426   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  470 + if (_fieldKey === 'stockUpCompanyId') {
  471 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  472 + } else {
  473 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  474 + }this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
427 475 },
428 476 onRadioSelect(field, nameField, opt) {
429 477 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -443,12 +491,15 @@ export default {
443 491 { key: 'unit', label: '单位' },
444 492 { key: 'workshopId', label: '生产厂' },
445 493 { key: 'specialTerms', label: '特别条款要求' },
  494 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
  495 + { key: 'region', label: '区域' },
446 496 ]
447 497 for (const it of checks) {
448 498 const val = this.form[it.key]
449 499 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
450 500 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
451 501 }
  502 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
452 503 const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
453 504 if (list.length === 0) {
454 505 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度(mm)">
57 57 <template v-slot:footer>
58   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差上限(mm)">
62 62 <template v-slot:footer>
63   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  63 + <uni-easyinput type="text" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差上限" @input="onNumberInput(idx, 'thicknessTolPos')" @blur="onNumberBlur(idx, 'thicknessTolPos', 9)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差下限(mm)">
68 68 <template v-slot:footer>
69   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  69 + <uni-easyinput type="text" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差下限" @input="onNumberInput(idx, 'thicknessTolNeg')" @blur="onNumberBlur(idx, 'thicknessTolNeg', 9)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度(mm)">
74 74 <template v-slot:footer>
75   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差上限(mm)">
79 79 <template v-slot:footer>
80   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  80 + <uni-easyinput type="text" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNumberInput(idx, 'widthTolPos')" @blur="onNumberBlur(idx, 'widthTolPos', 9)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差下限(mm)">
84 84 <template v-slot:footer>
85   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  85 + <uni-easyinput type="text" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNumberInput(idx, 'widthTolNeg')" @blur="onNumberBlur(idx, 'widthTolNeg', 9)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度(mm)">
89 89 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差上限(mm)">
94 94 <template v-slot:footer>
95   - <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  95 + <uni-easyinput type="text" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差上限" @input="onNumberInput(idx, 'lengthTolPos')" @blur="onNumberBlur(idx, 'lengthTolPos', 9)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差下限(mm)">
100 100 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  101 + <uni-easyinput type="text" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差下限" @input="onNumberInput(idx, 'lengthTolNeg')" @blur="onNumberBlur(idx, 'lengthTolNeg', 9)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量kg">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 9)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="销售价格">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 9)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="不含税金额">
... ... @@ -259,6 +259,61 @@ export default {
259 259 defaultItem() {
260 260 return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
261 261 },
  262 + onNumberInput(idx, field) {
  263 + const it = this.items[idx]
  264 + if (!it) return
  265 + let v = String(it[field] != null ? it[field] : '')
  266 + v = v.replace(/[^0-9.-]/g, '')
  267 + if ((v.match(/-/g) || []).length > 1) {
  268 + const first = v.indexOf('-') === 0 ? '-' : ''
  269 + v = first + v.replace(/-/g, '')
  270 + } else if (v.indexOf('-') > 0) {
  271 + v = v.replace(/-/g, '')
  272 + }
  273 + if ((v.match(/\./g) || []).length > 1) {
  274 + const parts = v.split('.')
  275 + v = parts[0] + '.' + parts.slice(1).join('')
  276 + }
  277 + it[field] = v
  278 + this.$set(this.items, idx, it)
  279 + },
  280 + onNumberBlur(idx, field, digits) {
  281 + const it = this.items[idx]
  282 + if (!it) return
  283 + let raw = it[field]
  284 + if (raw === '' || raw === null || raw === undefined || raw === '-') {
  285 + if (raw === '-') it[field] = ''
  286 + this.$set(this.items, idx, it)
  287 + return
  288 + }
  289 + let val = parseFloat(raw)
  290 + if (isNaN(val)) val = 0
  291 + const m = Math.pow(10, digits)
  292 + const rounded = Math.round(val * m) / m
  293 + it[field] = rounded
  294 + this.$set(this.items, idx, it)
  295 + },
  296 + validate() {
  297 + for (let i = 0; i < this.items.length; i++) {
  298 + const it = this.items[i]
  299 + const check = (pos, neg, label) => {
  300 + if (pos !== '' && pos !== null && pos !== undefined &&
  301 + neg !== '' && neg !== null && neg !== undefined) {
  302 + if (Number(pos) <= Number(neg)) {
  303 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  304 + }
  305 + }
  306 + return null
  307 + }
  308 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  309 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  310 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  311 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  312 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  313 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  314 + }
  315 + return true
  316 + },
262 317 onNonNegativeInput(idx, field) {
263 318 const it = this.items[idx]
264 319 if (!it) return
... ...
... ... @@ -21,7 +21,12 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
24   -
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
25 30 <uni-list-item title="订货日期">
26 31 <template v-slot:footer>
27 32 <uni-datetime-picker type="date" v-model="form.orderDate" />
... ... @@ -39,7 +44,18 @@
39 44 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 45 </template>
41 46 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
  47 + <uni-list-item title="办事处">
  48 + <template v-slot:footer>
  49 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  50 + </template>
  51 + </uni-list-item>
  52 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  53 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  54 + <template v-slot:body>
  55 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  56 + </template>
  57 + </uni-list-item>
  58 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 59 <uni-list-item title="合计人民币金额(大写)">
44 60 <template v-slot:footer>
45 61 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +224,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 224 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 225 import ProductRel from './productRel.vue'
210 226 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi,getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
  227 +import { getRetailCodeApi, createContractApi,getCustomerRemarks,getCustomerSpecificQualityRequirements, getDeptApi } from '@/api/contract'
212 228 import { getDicByCodes } from '@/utils/dic'
213 229 import { formatCurrencyToChinese } from '@/utils/common'
214 230 import { workshopQueryApi } from '@/api/devManage'
  231 +import { getArea } from '@/api/credit_manage.js'
215 232
216 233 export default {
217 234 name: 'AddContractStock',
... ... @@ -224,6 +241,8 @@ export default {
224 241 supplierName: '',
225 242 buyer: '',
226 243 buyerName: '',
  244 + stockUpCompanyId: '',
  245 + stockUpCompanyName: '',
227 246 orderDate: '',
228 247 deliveryDate: '',
229 248 designatedConsignee: '',
... ... @@ -242,6 +261,10 @@ export default {
242 261 destinationLabel: '',
243 262 workshopIdName: '',
244 263 workshopId: '',
  264 + deptName: '',
  265 + deptId: '',
  266 + region: '',
  267 + regionName: '',
245 268 remarks: '',
246 269 component: '',
247 270 packaging: '',
... ... @@ -263,12 +286,15 @@ export default {
263 286 productList: [],
264 287 customerRemarks: [],
265 288 defaultRemark: '',
  289 + regionOptions: [],
266 290 }
267 291 },
268 292 created() {
269 293 this.loadSuppliers()
270 294 this.loadExtraOptions()
271 295 this.initCode()
  296 + this.getDept()
  297 + this.loadRegionOptions()
272 298 this.form.orderDate = this.formatDate(new Date())
273 299 this.$nextTick(() => {
274 300 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -317,6 +343,24 @@ export default {
317 343 },
318 344 },
319 345 methods: {
  346 + async loadRegionOptions() {
  347 + try {
  348 + const res = await getArea()
  349 + const list = res.data || []
  350 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  351 + } catch (e) {
  352 + this.regionOptions = []
  353 + }
  354 + },
  355 + // 查询当前人所在办事处
  356 + getDept() {
  357 + getDeptApi().then(res => {
  358 + if (res.code === 200) {
  359 + this.form.deptName = res.data.name || ''
  360 + this.form.deptId = res.data.id || ''
  361 + }
  362 + })
  363 + },
320 364 getHistory() {
321 365 console.log('this.productLineList', this.productLineList[0].productId)
322 366 if (!this.productLineList.length || !this.productLineList[0].productId) {
... ... @@ -404,7 +448,7 @@ export default {
404 448 },
405 449 displayLabel(field) {
406 450 const m = this.form
407   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂' }
  451 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
408 452 const val = m[field]
409 453 return val ? String(val) : map[field]
410 454 },
... ... @@ -449,6 +493,8 @@ export default {
449 493 setSheet('单价中是否已包含运费', this.yesNoList)
450 494 } else if (field === 'historyRemarks') {
451 495 setSheet('历史备注', this.customerRemarks)
  496 + } else if (field === 'region') {
  497 + setSheet('区域', this.regionOptions)
452 498 }
453 499 },
454 500 onSheetConfirm({ value, label }) {
... ... @@ -467,6 +513,8 @@ export default {
467 513 let config = {}
468 514 if (fieldKey === 'buyer') {
469 515 config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  516 + } else if (fieldKey === 'stockUpCompanyId') {
  517 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
470 518 }
471 519 const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
472 520 this.sheet.visible = false
... ... @@ -477,7 +525,17 @@ export default {
477 525 const _fieldKey = this.relate.fieldKey
478 526 const first = (items && items.length > 0) ? items[0] : null
479 527 this.form[_fieldKey] = (first && first.id) ? first.id : ''
480   - this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  528 +
  529 + if (_fieldKey === 'stockUpCompanyId') {
  530 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  531 + } else {
  532 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  533 + }
  534 +
  535 + if (_fieldKey === 'buyer') {
  536 + this.form.stockUpCompanyId = (first && first.id) ? first.id : ''
  537 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  538 + }
481 539 },
482 540 onRadioSelect(field, nameField, opt) {
483 541 const val = opt && opt.value != null ? opt.value : ''
... ... @@ -543,6 +601,7 @@ export default {
543 601 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
544 602 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
545 603 }
  604 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
546 605 const list = Array.isArray(this.productLineList) ? this.productLineList : []
547 606 if (list.length === 0) {
548 607 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -17,11 +17,18 @@
17 17 }}</text></view>
18 18 <view class="row"><text class="label">需方</text><text class="value">{{ detail.buyerName || '-'
19 19 }}</text></view>
  20 + <view class="row"><text class="label">备货单位/人(生产标准)</text><text class="value">{{ detail.stockUpCompanyName || '-'
  21 + }}</text></view>
  22 +
20 23 <view class="row"><text class="label">订货日期</text><text class="value">{{ detail.orderDate }}</text>
21 24 </view>
22 25 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
23 26 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName || '-'
24   - }}</text></view>
  27 + }}</text></view>
  28 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  29 + }}</text></view>
  30 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  31 + }}</text></view>
25 32 </view>
26 33
27 34 <view class="section1">
... ... @@ -139,6 +146,11 @@ export default {
139 146 supplierName: '',
140 147 buyer: '',
141 148 buyerName: '',
  149 + stockUpCompanyId: '',
  150 + stockUpCompanyName: '',
  151 + deptName: '',
  152 + region: '',
  153 + regionName: '',
142 154 orderDate: '',
143 155 unit: '',
144 156 workshopId: '',
... ...
... ... @@ -22,6 +22,14 @@
22 22 </template>
23 23 </uni-list-item>
24 24
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 +
25 33 <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
26 34 @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
27 35 <template v-slot:body>
... ... @@ -40,8 +48,18 @@
40 48 <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
41 49 </template>
42 50 </uni-list-item>
43   -
44   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  51 + <uni-list-item title="办事处">
  52 + <template v-slot:footer>
  53 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  54 + </template>
  55 + </uni-list-item>
  56 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  57 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  58 + <template v-slot:body>
  59 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  60 + </template>
  61 + </uni-list-item>
  62 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 63
46 64 <uni-list-item title="合计人民币金额(大写)">
47 65 <template v-slot:footer>
... ... @@ -195,10 +213,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
195 213 import RelateSelectSheet from '@/components/relate-select/index.vue'
196 214 import ProductRel from './productRel.vue'
197 215 import CitySelector from '@/components/city-selector/index.vue'
198   -import { getContractApi, updateContractApi } from '@/api/contract'
  216 +import { getContractApi, updateContractApi, getDeptApi } from '@/api/contract'
199 217 import { getDicByCodes } from '@/utils/dic'
200 218 import { formatCurrencyToChinese } from '@/utils/common'
201 219 import { workshopQueryApi } from '@/api/devManage'
  220 +import { getArea } from '@/api/credit_manage.js'
202 221 export default {
203 222 name: 'ModifyContractStock',
204 223 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -212,8 +231,14 @@ export default {
212 231 supplierName: '',
213 232 buyer: '',
214 233 buyerName: '',
  234 + stockUpCompanyId: '',
  235 + stockUpCompanyName: '',
215 236 workshopId: '',
216 237 workshopName: '',
  238 + deptName: '',
  239 + deptId: '',
  240 + region: '',
  241 + regionName: '',
217 242 orderDate: '',
218 243 deliveryDate: '',
219 244 designatedConsignee: '',
... ... @@ -254,7 +279,8 @@ export default {
254 279 totalAmountIncludingTax: 0,
255 280 productLineList: [],
256 281 newProductLineList: [],
257   - productList: []
  282 + productList: [],
  283 + regionOptions: [],
258 284 }
259 285 },
260 286 onLoad(query) {
... ... @@ -264,6 +290,7 @@ export default {
264 290 this.loadSuppliers()
265 291 this.loadExtraOptions()
266 292 this.loadDetail()
  293 + this.loadRegionOptions()
267 294 this.$nextTick(() => {
268 295 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
269 296 this.initDestinationLabel()
... ... @@ -271,6 +298,15 @@ export default {
271 298 })
272 299 },
273 300 methods: {
  301 + async loadRegionOptions() {
  302 + try {
  303 + const res = await getArea()
  304 + const list = res.data || []
  305 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  306 + } catch (e) {
  307 + this.regionOptions = []
  308 + }
  309 + },
274 310 async loadDetail() {
275 311 if (!this.id) return
276 312 try {
... ... @@ -287,6 +323,12 @@ export default {
287 323 supplierName: m.supplierName || '',
288 324 buyer: m.buyer || (m.customer && m.customer.id) || '',
289 325 buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  326 + stockUpCompanyId: m.stockUpCompanyId || '',
  327 + stockUpCompanyName: m.stockUpCompanyName || '',
  328 + deptName: m.deptName || '',
  329 + deptId: m.deptId || '',
  330 + region: m.region || '',
  331 + regionName: m.regionName || '',
290 332 orderDate: m.orderDate || '',
291 333 designatedConsignee: m.designatedConsignee || '',
292 334 specialTerms: m.specialTerms || '',
... ... @@ -371,7 +413,7 @@ export default {
371 413 },
372 414 displayLabel(field) {
373 415 const m = this.form
374   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂' }
  416 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
375 417 const val = m[field]
376 418 return val ? String(val) : map[field]
377 419 },
... ... @@ -400,6 +442,8 @@ export default {
400 442 setSheet('单价中是否已包含包装费', this.yesNoList)
401 443 } else if (field === 'includesTransportFee') {
402 444 setSheet('单价中是否已包含运费', this.yesNoList)
  445 + } else if (field === 'region') {
  446 + setSheet('区域', this.regionOptions)
403 447 }
404 448 },
405 449 onSheetConfirm({ value, label }) {
... ... @@ -449,6 +493,7 @@ export default {
449 493 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
450 494 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
451 495 }
  496 + if (!this.$refs.productRel.validate()) return false
452 497 const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
453 498 if (list.length === 0) {
454 499 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度(mm)">
57 57 <template v-slot:footer>
58   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差上限(mm)">
62 62 <template v-slot:footer>
63   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  63 + <uni-easyinput type="text" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差上限" @input="onNumberInput(idx, 'thicknessTolPos')" @blur="onNumberBlur(idx, 'thicknessTolPos', 9)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差下限(mm)">
68 68 <template v-slot:footer>
69   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  69 + <uni-easyinput type="text" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差下限" @input="onNumberInput(idx, 'thicknessTolNeg')" @blur="onNumberBlur(idx, 'thicknessTolNeg', 9)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度(mm)">
74 74 <template v-slot:footer>
75   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差上限(mm)">
79 79 <template v-slot:footer>
80   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  80 + <uni-easyinput type="text" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNumberInput(idx, 'widthTolPos')" @blur="onNumberBlur(idx, 'widthTolPos', 9)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差下限(mm)">
84 84 <template v-slot:footer>
85   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  85 + <uni-easyinput type="text" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNumberInput(idx, 'widthTolNeg')" @blur="onNumberBlur(idx, 'widthTolNeg', 9)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度(mm)">
89 89 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差上限(mm)">
94 94 <template v-slot:footer>
95   - <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  95 + <uni-easyinput type="text" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差上限" @input="onNumberInput(idx, 'lengthTolPos')" @blur="onNumberBlur(idx, 'lengthTolPos', 9)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差下限(mm)">
100 100 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  101 + <uni-easyinput type="text" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差下限" @input="onNumberInput(idx, 'lengthTolNeg')" @blur="onNumberBlur(idx, 'lengthTolNeg', 9)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 9)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" disabled placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" disabled placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 9)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="不含税金额">
... ... @@ -257,6 +257,110 @@ export default {
257 257 this.recalculateAll()
258 258 },
259 259 methods: {
  260 + onNumberInput(idx, field) {
  261 + const it = this.items[idx]
  262 + if (!it) return
  263 + let v = String(it[field] != null ? it[field] : '')
  264 + // Allow numbers, decimal point, and negative sign
  265 + // But since this is a simple input, maybe just allow everything and validate later?
  266 + // Or better, restrict to valid number characters: 0-9, ., -
  267 + v = v.replace(/[^0-9.-]/g, '')
  268 +
  269 + // Handle multiple dots: keep only the first one
  270 + const parts = v.split('.')
  271 + if (parts.length > 2) {
  272 + v = parts[0] + '.' + parts.slice(1).join('')
  273 + }
  274 +
  275 + // Handle multiple negative signs: keep only at start
  276 + if (v.indexOf('-') > 0) {
  277 + v = v.replace(/-/g, '') // remove all
  278 + // Logic to put it back is complex if user types in middle,
  279 + // but standard behavior is usually just stripping invalid ones.
  280 + // Let's just strip non-leading minus
  281 + }
  282 + // A simpler regex approach for "start with optional minus, then digits/dots" is hard in one replace.
  283 + // Let's stick to a simple cleanup:
  284 +
  285 + // 1. Remove anything that is not digit, dot, or minus
  286 + v = v.replace(/[^0-9.-]/g, '')
  287 +
  288 + // 2. Ensure minus is only at index 0
  289 + if (v.lastIndexOf('-') > 0) {
  290 + v = (v.startsWith('-') ? '-' : '') + v.replace(/-/g, '')
  291 + }
  292 +
  293 + // 3. Ensure only one dot
  294 + const firstDotIndex = v.indexOf('.')
  295 + if (firstDotIndex !== -1) {
  296 + const before = v.substring(0, firstDotIndex + 1)
  297 + const after = v.substring(firstDotIndex + 1).replace(/\./g, '')
  298 + v = before + after
  299 + }
  300 +
  301 + // 4. If it starts with dot (or -. ), maybe prefix 0?
  302 + // -0.5 is valid. .5 is valid (becomes 0.5). -.5 becomes -0.5
  303 + if (v.startsWith('.')) v = '0' + v
  304 + if (v.startsWith('-.')) v = '-0' + v.substring(1)
  305 +
  306 + it[field] = v
  307 + this.$set(this.items, idx, it)
  308 + },
  309 + onNumberBlur(idx, field, digits) {
  310 + const it = this.items[idx]
  311 + if (!it) return
  312 + const raw = it[field]
  313 + if (raw === '' || raw === null || raw === undefined || raw === '-') {
  314 + // if just "-", clear it? or keep it? usually clear or 0.
  315 + // If it's optional tolerance, maybe empty string is better than 0 if user cleared it.
  316 + // But previously we used 0 for numbers.
  317 + // However, for tolerances, empty might mean "no tolerance specified".
  318 + // Let's check existing logic. onNonNegativeBlur sets to 0 if empty/invalid.
  319 + // For tolerance, maybe we want to allow empty?
  320 + // The requirement says "两个都有值时,上限 要大于 下限".
  321 + // If I set to 0, then 0 > 0 is false.
  322 + // Let's assume empty is allowed.
  323 + // But wait, "number type".
  324 + // Let's try to parse.
  325 + if (raw === '' || raw === null || raw === undefined) {
  326 + this.$set(this.items, idx, it)
  327 + return
  328 + }
  329 + }
  330 +
  331 + let num = this.toNumber(raw)
  332 + if (isNaN(num)) {
  333 + // If invalid input, maybe reset to empty or 0?
  334 + // Let's set to 0 if it was required, but tolerance might be optional.
  335 + // If the user entered garbage, clear it.
  336 + it[field] = ''
  337 + } else {
  338 + const rounded = this.round(num, digits)
  339 + it[field] = rounded
  340 + }
  341 + this.$set(this.items, idx, it)
  342 + },
  343 + validate() {
  344 + for (let i = 0; i < this.items.length; i++) {
  345 + const it = this.items[i]
  346 + const check = (pos, neg, label) => {
  347 + if (pos !== '' && pos !== null && pos !== undefined &&
  348 + neg !== '' && neg !== null && neg !== undefined) {
  349 + if (Number(pos) <= Number(neg)) {
  350 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  351 + }
  352 + }
  353 + return null
  354 + }
  355 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  356 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  357 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  358 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  359 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  360 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  361 + }
  362 + return true
  363 + },
260 364 defaultItem() {
261 365 return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
262 366 },
... ...
... ... @@ -21,6 +21,13 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
  30 +
24 31
25 32 <uni-list-item title="订货日期">
26 33 <template v-slot:footer>
... ... @@ -39,7 +46,18 @@
39 46 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 47 </template>
41 48 </uni-list-item>
42   - <ProductRel mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
  49 + <uni-list-item title="办事处">
  50 + <template v-slot:footer>
  51 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  52 + </template>
  53 + </uni-list-item>
  54 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  55 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  56 + <template v-slot:body>
  57 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  58 + </template>
  59 + </uni-list-item>
  60 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 61 <uni-list-item title="合计人民币金额(大写)">
44 62 <template v-slot:footer>
45 63 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -208,10 +226,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
208 226 import RelateSelectSheet from '@/components/relate-select/index.vue'
209 227 import ProductRel from './productRel.vue'
210 228 import CitySelector from '@/components/city-selector/index.vue'
211   -import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
  229 +import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements, getDeptApi } from '@/api/contract'
212 230 import { getDicByCodes } from '@/utils/dic'
213 231 import { formatCurrencyToChinese } from '@/utils/common'
214 232 import { workshopQueryApi } from '@/api/devManage'
  233 +import { getArea } from '@/api/credit_manage.js'
215 234
216 235 export default {
217 236 name: 'AddContractUnplan',
... ... @@ -224,6 +243,8 @@ export default {
224 243 supplierName: '',
225 244 buyer: '',
226 245 buyerName: '',
  246 + stockUpCompanyId: '',
  247 + stockUpCompanyName: '',
227 248 orderDate: '',
228 249 deliveryDate: '',
229 250 designatedConsignee: '',
... ... @@ -242,6 +263,10 @@ export default {
242 263 destinationLabel: '',
243 264 workshopIdName: '',
244 265 workshopId: '',
  266 + deptName: '',
  267 + deptId: '',
  268 + region: '',
  269 + regionName: '',
245 270 remarks: '',
246 271 component: '',
247 272 packaging: '',
... ... @@ -263,12 +288,15 @@ export default {
263 288 productList: [],
264 289 customerRemarks: [],
265 290 defaultRemark: '',
  291 + regionOptions: [],
266 292 }
267 293 },
268 294 created() {
269 295 this.loadSuppliers()
270 296 this.loadExtraOptions()
271 297 this.initCode()
  298 + this.getDept()
  299 + this.loadRegionOptions()
272 300 this.form.orderDate = this.formatDate(new Date())
273 301 this.$nextTick(() => {
274 302 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
... ... @@ -319,6 +347,24 @@ export default {
319 347 },
320 348 },
321 349 methods: {
  350 + async loadRegionOptions() {
  351 + try {
  352 + const res = await getArea()
  353 + const list = res.data || []
  354 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  355 + } catch (e) {
  356 + this.regionOptions = []
  357 + }
  358 + },
  359 + // 查询当前人所在办事处
  360 + getDept() {
  361 + getDeptApi().then(res => {
  362 + if (res.code === 200) {
  363 + this.form.deptName = res.data.name || ''
  364 + this.form.deptId = res.data.id || ''
  365 + }
  366 + })
  367 + },
322 368 getHistory() {
323 369 console.log('this.productLineList', this.productLineList[0].productId)
324 370 if (!this.productLineList.length || !this.productLineList[0].productId) {
... ... @@ -407,7 +453,7 @@ export default {
407 453 },
408 454 displayLabel(field) {
409 455 const m = this.form
410   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂' }
  456 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopIdName: '请选择生产厂', regionName: '请选择区域' }
411 457 const val = m[field]
412 458 return val ? String(val) : map[field]
413 459 },
... ... @@ -452,6 +498,8 @@ export default {
452 498 setSheet('单价中是否已包含运费', this.yesNoList)
453 499 } else if (field === 'historyRemarks') {
454 500 setSheet('历史备注', this.customerRemarks)
  501 + } else if (field === 'region') {
  502 + setSheet('区域', this.regionOptions)
455 503 }
456 504 },
457 505 onSheetConfirm({ value, label }) {
... ... @@ -546,6 +594,7 @@ export default {
546 594 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
547 595 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
548 596 }
  597 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
549 598 const list = Array.isArray(this.productLineList) ? this.productLineList : []
550 599 if (list.length === 0) {
551 600 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ...
... ... @@ -23,6 +23,10 @@
23 23 <view class="row"><text class="label">单位</text><text class="value">{{ detail.unit }}</text></view>
24 24 <view class="row"><text class="label">生产厂</text><text class="value">{{ detail.workshopName || '-'
25 25 }}</text></view>
  26 + <view class="row"><text class="label">办事处</text><text class="value">{{ detail.deptName || '-'
  27 + }}</text></view>
  28 + <view class="row"><text class="label">区域</text><text class="value">{{ detail.regionName || '-'
  29 + }}</text></view>
26 30 </view>
27 31
28 32 <view class="section1">
... ... @@ -470,6 +474,11 @@ export default {
470 474 this.detail = {
471 475 ...this.detail,
472 476 ...data,
  477 + stockUpCompanyId: data.stockUpCompanyId || '',
  478 + stockUpCompanyName: data.stockUpCompanyName || '',
  479 + deptName: data.deptName || '',
  480 + region: data.region || '',
  481 + regionName: data.regionName || '',
473 482 includesPackagingFeeName, includesTransportFeeName,
474 483 destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',
475 484 destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '',
... ...
... ... @@ -21,7 +21,12 @@
21 21 <view class="item-title"><text class="required">*</text><text>需方</text></view>
22 22 </template>
23 23 </uni-list-item>
24   -
  24 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  25 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  26 + <template v-slot:body>
  27 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  28 + </template>
  29 + </uni-list-item>
25 30 <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
26 31 @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
27 32 <template v-slot:body>
... ... @@ -40,8 +45,18 @@
40 45 <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
41 46 </template>
42 47 </uni-list-item>
43   -
44   - <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  48 + <uni-list-item title="办事处">
  49 + <template v-slot:footer>
  50 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  51 + </template>
  52 + </uni-list-item>
  53 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  54 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  55 + <template v-slot:body>
  56 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  57 + </template>
  58 + </uni-list-item>
  59 + <ProductRel ref="productRel" mode="add" :deliveryDateBase="form.deliveryDate" :deliveryDate="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 60
46 61 <uni-list-item title="合计人民币金额(大写)">
47 62 <template v-slot:footer>
... ... @@ -195,10 +210,11 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
195 210 import RelateSelectSheet from '@/components/relate-select/index.vue'
196 211 import ProductRel from './productRel.vue'
197 212 import CitySelector from '@/components/city-selector/index.vue'
198   -import { getContractApi, updateContractApi } from '@/api/contract'
  213 +import { getContractApi, updateContractApi, getDeptApi } from '@/api/contract'
199 214 import { getDicByCodes } from '@/utils/dic'
200 215 import { formatCurrencyToChinese } from '@/utils/common'
201 216 import { workshopQueryApi } from '@/api/devManage'
  217 +import { getArea } from '@/api/credit_manage.js'
202 218 export default {
203 219 name: 'ModifyContractUnplan',
204 220 components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
... ... @@ -212,8 +228,14 @@ export default {
212 228 supplierName: '',
213 229 buyer: '',
214 230 buyerName: '',
  231 + stockUpCompanyId: '',
  232 + stockUpCompanyName: '',
215 233 workshopId: '',
216 234 workshopName: '',
  235 + deptName: '',
  236 + deptId: '',
  237 + region: '',
  238 + regionName: '',
217 239 orderDate: '',
218 240 deliveryDate: '',
219 241 designatedConsignee: '',
... ... @@ -254,7 +276,8 @@ export default {
254 276 totalAmountIncludingTax: 0,
255 277 productLineList: [],
256 278 newProductLineList: [],
257   - productList: []
  279 + productList: [],
  280 + regionOptions: [],
258 281 }
259 282 },
260 283 onLoad(query) {
... ... @@ -264,6 +287,7 @@ export default {
264 287 this.loadSuppliers()
265 288 this.loadExtraOptions()
266 289 this.loadDetail()
  290 + this.loadRegionOptions()
267 291 this.$nextTick(() => {
268 292 if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
269 293 this.initDestinationLabel()
... ... @@ -271,6 +295,15 @@ export default {
271 295 })
272 296 },
273 297 methods: {
  298 + async loadRegionOptions() {
  299 + try {
  300 + const res = await getArea()
  301 + const list = res.data || []
  302 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  303 + } catch (e) {
  304 + this.regionOptions = []
  305 + }
  306 + },
274 307 async loadDetail() {
275 308 if (!this.id) return
276 309 try {
... ... @@ -287,6 +320,12 @@ export default {
287 320 supplierName: m.supplierName || '',
288 321 buyer: m.buyer || (m.customer && m.customer.id) || '',
289 322 buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  323 + stockUpCompanyId: m.stockUpCompanyId || '',
  324 + stockUpCompanyName: m.stockUpCompanyName || '',
  325 + deptName: m.deptName || '',
  326 + deptId: m.deptId || '',
  327 + region: m.region || '',
  328 + regionName: m.regionName || '',
290 329 orderDate: m.orderDate || '',
291 330 designatedConsignee: m.designatedConsignee || '',
292 331 specialTerms: m.specialTerms || '',
... ... @@ -371,7 +410,7 @@ export default {
371 410 },
372 411 displayLabel(field) {
373 412 const m = this.form
374   - const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂' }
  413 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
375 414 const val = m[field]
376 415 return val ? String(val) : map[field]
377 416 },
... ... @@ -400,6 +439,8 @@ export default {
400 439 setSheet('单价中是否已包含包装费', this.yesNoList)
401 440 } else if (field === 'includesTransportFee') {
402 441 setSheet('单价中是否已包含运费', this.yesNoList)
  442 + } else if (field === 'region') {
  443 + setSheet('区域', this.regionOptions)
403 444 }
404 445 },
405 446 onSheetConfirm({ value, label }) {
... ... @@ -439,9 +480,11 @@ export default {
439 480 { key: 'code', label: '编号' },
440 481 { key: 'supplier', label: '供方' },
441 482 { key: 'buyer', label: '需方' },
  483 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
442 484 { key: 'orderDate', label: '订货日期' },
443 485 { key: 'unit', label: '单位' },
444 486 { key: 'workshopId', label: '生产厂' },
  487 + { key: 'region', label: '区域' },
445 488 { key: 'specialTerms', label: '特别条款要求' },
446 489 ]
447 490 for (const it of checks) {
... ... @@ -449,6 +492,7 @@ export default {
449 492 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
450 493 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
451 494 }
  495 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
452 496 const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
453 497 if (list.length === 0) {
454 498 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
... ... @@ -752,4 +796,4 @@ export default {
752 796 }
753 797 }
754 798
755   -</style>
\ No newline at end of file
  799 +</style>
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度(mm)">
57 57 <template v-slot:footer>
58   - <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 9)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差上限(mm)">
62 62 <template v-slot:footer>
63   - <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差上限" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
  63 + <uni-easyinput type="text" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差上限" @input="onNumberInput(idx, 'thicknessTolPos')" @blur="onNumberBlur(idx, 'thicknessTolPos', 9)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差下限(mm)">
68 68 <template v-slot:footer>
69   - <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差下限" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
  69 + <uni-easyinput type="text" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差下限" @input="onNumberInput(idx, 'thicknessTolNeg')" @blur="onNumberBlur(idx, 'thicknessTolNeg', 9)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度(mm)">
74 74 <template v-slot:footer>
75   - <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 9)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差上限(mm)">
79 79 <template v-slot:footer>
80   - <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
  80 + <uni-easyinput type="text" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差上限" @input="onNumberInput(idx, 'widthTolPos')" @blur="onNumberBlur(idx, 'widthTolPos', 9)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差下限(mm)">
84 84 <template v-slot:footer>
85   - <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
  85 + <uni-easyinput type="text" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差下限" @input="onNumberInput(idx, 'widthTolNeg')" @blur="onNumberBlur(idx, 'widthTolNeg', 9)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度(mm)">
89 89 <template v-slot:footer>
90   - <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 9)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差上限(mm)">
94 94 <template v-slot:footer>
95   - <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差上限" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
  95 + <uni-easyinput type="text" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差上限" @input="onNumberInput(idx, 'lengthTolPos')" @blur="onNumberBlur(idx, 'lengthTolPos', 9)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差下限(mm)">
100 100 <template v-slot:footer>
101   - <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差下限" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
  101 + <uni-easyinput type="text" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差下限" @input="onNumberInput(idx, 'lengthTolNeg')" @blur="onNumberBlur(idx, 'lengthTolNeg', 9)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 9)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 9)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="不含税金额">
... ... @@ -297,6 +297,52 @@ export default {
297 297 this.$set(this.items, idx, it)
298 298 if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
299 299 },
  300 + onNumberInput(idx, field) {
  301 + const it = this.items[idx]
  302 + if (!it) return
  303 + let v = String(it[field] != null ? it[field] : '')
  304 + v = v.replace(/[^0-9.\-]/g, '')
  305 + v = v.replace(/(\..*)\./g, '$1')
  306 + v = v.replace(/(?!^)-/g, '')
  307 + if (v.startsWith('.')) v = '0' + v
  308 + if (v.startsWith('-.')) v = '-0' + v.slice(1)
  309 + it[field] = v
  310 + this.$set(this.items, idx, it)
  311 + },
  312 + onNumberBlur(idx, field, digits) {
  313 + const it = this.items[idx]
  314 + if (!it) return
  315 + const raw = it[field]
  316 + if (raw === '' || raw === null || raw === undefined) {
  317 + this.$set(this.items, idx, it)
  318 + return
  319 + }
  320 + let num = this.toNumber(raw)
  321 + const rounded = this.round(num, digits)
  322 + it[field] = rounded
  323 + this.$set(this.items, idx, it)
  324 + },
  325 + validate() {
  326 + for (let i = 0; i < this.items.length; i++) {
  327 + const it = this.items[i]
  328 + const check = (pos, neg, label) => {
  329 + if (pos !== '' && pos !== null && pos !== undefined &&
  330 + neg !== '' && neg !== null && neg !== undefined) {
  331 + if (Number(pos) <= Number(neg)) {
  332 + return `第${i + 1}行产品:${label}公差上限必须大于下限`
  333 + }
  334 + }
  335 + return null
  336 + }
  337 + let err = check(it.thicknessTolPos, it.thicknessTolNeg, '厚度')
  338 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  339 + err = check(it.widthTolPos, it.widthTolNeg, '宽度')
  340 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  341 + err = check(it.lengthTolPos, it.lengthTolNeg, '长度')
  342 + if (err) { uni.showToast({ title: err, icon: 'none' }); return false }
  343 + }
  344 + return true
  345 + },
300 346 formatCurrency(val) {
301 347 if (val == null || val === '') return ''
302 348 const num = Number(val)
... ...
... ... @@ -14,26 +14,41 @@
14 14 </template>
15 15 </uni-list-item>
16 16
  17 + <uni-list-item title="办事处">
  18 + <template v-slot:body>
  19 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  20 + </template>
  21 + <template v-slot:footer>
  22 + <view class="readonly-text">{{ form.deptName }}</view>
  23 + </template>
  24 + </uni-list-item>
  25 +
17 26 <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
18 27 @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
19 28 <template v-slot:body>
20   - <view class="item-title"><text>区域</text></view>
  29 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
21 30 </template>
22 31 </uni-list-item>
23   - <uni-list-item title="客户简称">
  32 + <uni-list-item class="select-item" :class="form.customerShortName ? 'is-filled' : 'is-empty'">
  33 + <template v-slot:body>
  34 + <view class="item-title"><text class="required">*</text><text>简写名称</text></view>
  35 + </template>
24 36 <template v-slot:footer>
25   - <uni-easyinput v-model="form.customerShortName" placeholder="请输入客户简称" :inputBorder="false" />
  37 + <uni-easyinput v-model="form.customerShortName" placeholder="请输入简写名称" :inputBorder="false" />
26 38 </template>
27 39 </uni-list-item>
28 40
29 41 <uni-list-item class="select-item" :class="form.enterpriseType ? 'is-filled' : 'is-empty'" clickable
30 42 @click="openSheet('enterpriseType')" :rightText="displayLabel('enterpriseTypeName')" showArrow>
31 43 <template v-slot:body>
32   - <view class="item-title"><text>企业类型</text></view>
  44 + <view class="item-title"><text class="required">*</text><text>企业类型</text></view>
33 45 </template>
34 46 </uni-list-item>
35 47
36 48 <uni-list-item class="mgb10" title="登记日期">
  49 + <template v-slot:body>
  50 + <view class="item-title"><text class="required">*</text><text>登记日期</text></view>
  51 + </template>
37 52 <template v-slot:footer>
38 53 <uni-datetime-picker type="date" v-model="form.registerDate" />
39 54 </template>
... ... @@ -251,7 +266,7 @@
251 266 </uni-list-item>
252 267 <uni-list-item class="amount-item">
253 268 <template v-slot:body>
254   - <view class="item-title"><text>授信额度</text></view>
  269 + <view class="item-title"><text class="required">*</text><text>授信额度</text></view>
255 270 </template>
256 271 <template v-slot:footer>
257 272 <view class="amount-row">
... ... @@ -261,6 +276,9 @@
261 276 </template>
262 277 </uni-list-item>
263 278 <uni-list-item title="结算期限">
  279 + <template v-slot:body>
  280 + <view class="item-title"><text class="required">*</text><text>结算期限</text></view>
  281 + </template>
264 282 <template v-slot:footer>
265 283 <uni-easyinput v-model="form.settlementPeriod" placeholder="请输入结算期限" :inputBorder="false" />
266 284 </template>
... ... @@ -309,7 +327,8 @@
309 327 @confirm="onSheetConfirm" />
310 328 <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
311 329 :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
312   - :selectedKeys.sync="relate.selectedKeys" :source-extra="{ source: 'CUSTOMER_CREDIT' }" @confirm="onRelateConfirm" />
  330 + :selectedKeys.sync="relate.selectedKeys" :source-extra="{ source: 'CUSTOMER_CREDIT' }"
  331 + @confirm="onRelateConfirm" />
313 332 </view>
314 333
315 334 </template>
... ... @@ -320,6 +339,7 @@ import RelateSelectSheet from '@/components/relate-select/index.vue'
320 339 import { generateCreditCode, getAllUser, getDeptUser, createApi, getArea } from '@/api/credit_manage.js'
321 340 import { getDicByCodeApi } from '@/api/base.js'
322 341 import CorePersonnel from './corePersonnel.vue'
  342 +import { getDeptApi } from '@/api/contract'
323 343
324 344 export default {
325 345 name: 'CreditManageAdd',
... ... @@ -379,6 +399,8 @@ export default {
379 399 mainIndustry: '',
380 400 annualMaterialOverview: '',
381 401 corePersonnelList: [],
  402 + deptName: '',
  403 + deptId: '',
382 404 },
383 405 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
384 406 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
... ... @@ -391,6 +413,7 @@ export default {
391 413 }
392 414 },
393 415 created() {
  416 + this.getDept()
394 417 this.loadSerialNumber()
395 418 this.loadRegionOptions()
396 419 this.loadEnterpriseTypeOptions()
... ... @@ -401,6 +424,15 @@ export default {
401 424 this.loadGenderOptions()
402 425 },
403 426 methods: {
  427 + // 查询当前人所在办事处
  428 + getDept() {
  429 + getDeptApi().then(res => {
  430 + if (res.code === 200) {
  431 + this.form.deptName = res.data.name || ''
  432 + this.form.deptId = res.data.id || ''
  433 + }
  434 + })
  435 + },
404 436 async loadSerialNumber() {
405 437 try {
406 438 const res = await generateCreditCode()
... ... @@ -428,13 +460,13 @@ export default {
428 460 if (field === 'region') {
429 461 setSheet('区域', this.regionOptions)
430 462 } else
431   - if (field === 'enterpriseType') {
432   - setSheet('企业类型', this.enterpriseTypeOptions)
433   - } else if (field === 'suggestedCategory') {
434   - setSheet('建议客户分类', this.categoryOptions)
435   - } else if (field === 'investigator') {
436   - setSheet('调查人', this.investigatorOptions)
437   - }
  463 + if (field === 'enterpriseType') {
  464 + setSheet('企业类型', this.enterpriseTypeOptions)
  465 + } else if (field === 'suggestedCategory') {
  466 + setSheet('建议客户分类', this.categoryOptions)
  467 + } else if (field === 'investigator') {
  468 + setSheet('调查人', this.investigatorOptions)
  469 + }
438 470 },
439 471 onSheetConfirm({ value, label }) {
440 472 const field = this.sheet.field
... ... @@ -478,12 +510,21 @@ export default {
478 510 validateRequired() {
479 511 const checks = [
480 512 { key: 'serialNumber', label: '编号' },
481   - { key: 'companyId', label: '单位名称' }
  513 + { key: 'deptId', label: '办事处' },
  514 + { key: 'region', label: '区域' },
  515 + { key: 'customerShortName', label: '简写名称' },
  516 + { key: 'enterpriseType', label: '企业类型' },
  517 + { key: 'registerDate', label: '登记日期' },
  518 + { key: 'companyId', label: '单位名称' },
  519 + { key: 'creditLimit', label: '授信额度' },
  520 + { key: 'settlementPeriod', label: '结算期限' }
482 521 ]
483 522 for (const it of checks) {
484 523 const val = this.form[it.key]
485 524 if (val === undefined || val === null || String(val).trim() === '') {
486   - uni.showToast({ title: `请先选择${it.label}`, icon: 'none' })
  525 + const isInput = ['customerShortName', 'settlementPeriod', 'creditLimit'].includes(it.key);
  526 + const verb = isInput ? '输入' : '选择';
  527 + uni.showToast({ title: `请先${verb}${it.label}`, icon: 'none' })
487 528 return false
488 529 }
489 530 }
... ... @@ -558,7 +599,7 @@ export default {
558 599 },
559 600 async onSubmit() {
560 601 if (!this.validateRequired()) return
561   - const payload = {
  602 + const payload = {
562 603 ...this.form,
563 604 status: 'AUDIT'
564 605 }
... ... @@ -573,6 +614,7 @@ export default {
573 614 delete payload.suggestedCategoryName
574 615 delete payload.companyIdName
575 616 delete payload.investigatorName
  617 + delete payload.deptName
576 618 try {
577 619 await createApi(payload)
578 620 uni.showToast({ title: '提交成功', icon: 'success' })
... ... @@ -760,4 +802,15 @@ export default {
760 802 }
761 803 }
762 804 }
  805 +
  806 +
  807 +/* 只读文本样式 */
  808 +.readonly-text {
  809 + color: rgba(0, 0, 0, 0.9);
  810 + font-size: 32rpx;
  811 + line-height: 48rpx;
  812 + text-align: right;
  813 + white-space: pre-wrap;
  814 + word-break: break-all;
  815 +}
763 816 </style>
... ...
... ... @@ -13,26 +13,41 @@
13 13 </template>
14 14 </uni-list-item>
15 15
  16 + <uni-list-item title="办事处">
  17 + <template v-slot:body>
  18 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  19 + </template>
  20 + <template v-slot:footer>
  21 + <view class="readonly-text">{{ form.deptName }}</view>
  22 + </template>
  23 + </uni-list-item>
  24 +
16 25 <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
17 26 @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
18 27 <template v-slot:body>
19   - <view class="item-title"><text>区域</text></view>
  28 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
20 29 </template>
21 30 </uni-list-item>
22   - <uni-list-item title="客户简称">
  31 + <uni-list-item class="select-item" :class="form.customerShortName ? 'is-filled' : 'is-empty'">
  32 + <template v-slot:body>
  33 + <view class="item-title"><text class="required">*</text><text>简写名称</text></view>
  34 + </template>
23 35 <template v-slot:footer>
24   - <uni-easyinput v-model="form.customerShortName" placeholder="请输入客户简称" :inputBorder="false" />
  36 + <uni-easyinput v-model="form.customerShortName" placeholder="请输入简写名称" :inputBorder="false" />
25 37 </template>
26 38 </uni-list-item>
27 39
28 40 <uni-list-item class="select-item" :class="form.enterpriseType ? 'is-filled' : 'is-empty'" clickable
29 41 @click="openSheet('enterpriseType')" :rightText="displayLabel('enterpriseTypeName')" showArrow>
30 42 <template v-slot:body>
31   - <view class="item-title"><text>企业类型</text></view>
  43 + <view class="item-title"><text class="required">*</text><text>企业类型</text></view>
32 44 </template>
33 45 </uni-list-item>
34 46
35 47 <uni-list-item class="mgb10" title="登记日期">
  48 + <template v-slot:body>
  49 + <view class="item-title"><text class="required">*</text><text>登记日期</text></view>
  50 + </template>
36 51 <template v-slot:footer>
37 52 <uni-datetime-picker type="date" v-model="form.registerDate" />
38 53 </template>
... ... @@ -250,7 +265,7 @@
250 265 </uni-list-item>
251 266 <uni-list-item class="amount-item">
252 267 <template v-slot:body>
253   - <view class="item-title"><text>授信额度</text></view>
  268 + <view class="item-title"><text class="required">*</text><text>授信额度</text></view>
254 269 </template>
255 270 <template v-slot:footer>
256 271 <view class="amount-row">
... ... @@ -260,6 +275,9 @@
260 275 </template>
261 276 </uni-list-item>
262 277 <uni-list-item title="结算期限">
  278 + <template v-slot:body>
  279 + <view class="item-title"><text class="required">*</text><text>结算期限</text></view>
  280 + </template>
263 281 <template v-slot:footer>
264 282 <uni-easyinput v-model="form.settlementPeriod" placeholder="请输入结算期限" :inputBorder="false" />
265 283 </template>
... ... @@ -506,12 +524,21 @@ export default {
506 524 validateRequired() {
507 525 const checks = [
508 526 { key: 'serialNumber', label: '编号' },
509   - { key: 'companyId', label: '单位名称' }
  527 + { key: 'deptName', label: '办事处' },
  528 + { key: 'region', label: '区域' },
  529 + { key: 'customerShortName', label: '简写名称' },
  530 + { key: 'enterpriseType', label: '企业类型' },
  531 + { key: 'registerDate', label: '登记日期' },
  532 + { key: 'companyId', label: '单位名称' },
  533 + { key: 'creditLimit', label: '授信额度' },
  534 + { key: 'settlementPeriod', label: '结算期限' }
510 535 ]
511 536 for (const it of checks) {
512 537 const val = this.form[it.key]
513 538 if (val === undefined || val === null || String(val).trim() === '') {
514   - uni.showToast({ title: `请先选择${it.label}`, icon: 'none' })
  539 + const isInput = ['customerShortName', 'settlementPeriod', 'creditLimit'].includes(it.key);
  540 + const verb = isInput ? '输入' : '选择';
  541 + uni.showToast({ title: `请先${verb}${it.label}`, icon: 'none' })
515 542 return false
516 543 }
517 544 }
... ... @@ -616,6 +643,7 @@ export default {
616 643 padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
617 644 background: #fff;
618 645 box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  646 + z-index: 10;
619 647
620 648 .btn {
621 649 height: 80rpx;
... ... @@ -758,4 +786,13 @@ export default {
758 786 }
759 787 }
760 788 }
  789 +/* 只读文本样式 */
  790 +.readonly-text {
  791 + color: rgba(0, 0, 0, 0.9);
  792 + font-size: 32rpx;
  793 + line-height: 48rpx;
  794 + text-align: right;
  795 + white-space: pre-wrap;
  796 + word-break: break-all;
  797 +}
761 798 </style>
... ...
... ... @@ -6,8 +6,9 @@
6 6 <text class="row company">{{ form.companyName }}</text>
7 7 <view :class="['status', `status_${form.status}`]" />
8 8 <view class="row"><text class="label">编号</text><text class="value">{{ form.serialNumber }}</text></view>
  9 + <view class="row"><text class="label">办事处</text><text class="value">{{ form.deptName }}</text></view>
9 10 <view class="row"><text class="label">区域</text><text class="value">{{ form.regionName }}</text></view>
10   - <view class="row"><text class="label">客户简称</text><text class="value">{{ form.customerShortName }}</text>
  11 + <view class="row"><text class="label">简写名称</text><text class="value">{{ form.customerShortName }}</text>
11 12 </view>
12 13 <view class="row"><text class="label">企业类型</text><text class="value">{{ getDicName('ENTERPRISE_TYPE',
13 14 form.enterpriseType, enterpriseTypeOptions) }}</text></view>
... ...
... ... @@ -13,26 +13,40 @@
13 13 </template>
14 14 </uni-list-item>
15 15
  16 + <uni-list-item title="办事处">
  17 + <template v-slot:body>
  18 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  19 + </template>
  20 + <template v-slot:footer>
  21 + <view class="readonly-text">{{ form.deptName }}</view>
  22 + </template>
  23 + </uni-list-item>
16 24 <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
17 25 @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
18 26 <template v-slot:body>
19   - <view class="item-title"><text>区域</text></view>
  27 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
20 28 </template>
21 29 </uni-list-item>
22   - <uni-list-item title="客户简称">
  30 + <uni-list-item class="select-item" :class="form.customerShortName ? 'is-filled' : 'is-empty'">
  31 + <template v-slot:body>
  32 + <view class="item-title"><text class="required">*</text><text>简写名称</text></view>
  33 + </template>
23 34 <template v-slot:footer>
24   - <uni-easyinput v-model="form.customerShortName" placeholder="请输入客户简称" :inputBorder="false" />
  35 + <uni-easyinput v-model="form.customerShortName" placeholder="请输入简写名称" :inputBorder="false" />
25 36 </template>
26 37 </uni-list-item>
27 38
28 39 <uni-list-item class="select-item" :class="form.enterpriseType ? 'is-filled' : 'is-empty'" clickable
29 40 @click="openSheet('enterpriseType')" :rightText="displayLabel('enterpriseTypeName')" showArrow>
30 41 <template v-slot:body>
31   - <view class="item-title"><text>企业类型</text></view>
  42 + <view class="item-title"><text class="required">*</text><text>企业类型</text></view>
32 43 </template>
33 44 </uni-list-item>
34 45
35 46 <uni-list-item class="mgb10" title="登记日期">
  47 + <template v-slot:body>
  48 + <view class="item-title"><text class="required">*</text><text>登记日期</text></view>
  49 + </template>
36 50 <template v-slot:footer>
37 51 <uni-datetime-picker type="date" v-model="form.registerDate" />
38 52 </template>
... ... @@ -250,7 +264,7 @@
250 264 </uni-list-item>
251 265 <uni-list-item class="amount-item">
252 266 <template v-slot:body>
253   - <view class="item-title"><text>授信额度</text></view>
  267 + <view class="item-title"><text class="required">*</text><text>授信额度</text></view>
254 268 </template>
255 269 <template v-slot:footer>
256 270 <view class="amount-row">
... ... @@ -260,6 +274,9 @@
260 274 </template>
261 275 </uni-list-item>
262 276 <uni-list-item title="结算期限">
  277 + <template v-slot:body>
  278 + <view class="item-title"><text class="required">*</text><text>结算期限</text></view>
  279 + </template>
263 280 <template v-slot:footer>
264 281 <uni-easyinput v-model="form.settlementPeriod" placeholder="请输入结算期限" :inputBorder="false" />
265 282 </template>
... ... @@ -506,12 +523,21 @@ export default {
506 523 validateRequired() {
507 524 const checks = [
508 525 { key: 'serialNumber', label: '编号' },
509   - { key: 'companyId', label: '单位名称' }
  526 + { key: 'deptName', label: '办事处' },
  527 + { key: 'region', label: '区域' },
  528 + { key: 'customerShortName', label: '简写名称' },
  529 + { key: 'enterpriseType', label: '企业类型' },
  530 + { key: 'registerDate', label: '登记日期' },
  531 + { key: 'companyId', label: '单位名称' },
  532 + { key: 'creditLimit', label: '授信额度' },
  533 + { key: 'settlementPeriod', label: '结算期限' }
510 534 ]
511 535 for (const it of checks) {
512 536 const val = this.form[it.key]
513 537 if (val === undefined || val === null || String(val).trim() === '') {
514   - uni.showToast({ title: `请先选择${it.label}`, icon: 'none' })
  538 + const isInput = ['customerShortName', 'settlementPeriod', 'creditLimit'].includes(it.key);
  539 + const verb = isInput ? '输入' : '选择';
  540 + uni.showToast({ title: `请先${verb}${it.label}`, icon: 'none' })
515 541 return false
516 542 }
517 543 }
... ... @@ -759,4 +785,13 @@ export default {
759 785 }
760 786 }
761 787 }
  788 +/* 只读文本样式 */
  789 +.readonly-text {
  790 + color: rgba(0, 0, 0, 0.9);
  791 + font-size: 32rpx;
  792 + line-height: 48rpx;
  793 + text-align: right;
  794 + white-space: pre-wrap;
  795 + word-break: break-all;
  796 +}
762 797 </style>
... ...
... ... @@ -3,8 +3,9 @@
3 3 <view class="section">
4 4 <text class="row company">{{ form.companyName }}</text>
5 5 <view class="row"><text class="label">编号</text><text class="value">{{ form.serialNumber }}</text></view>
  6 + <view class="row"><text class="label">办事处</text><text class="value">{{ form.deptName }}</text></view>
6 7 <view class="row"><text class="label">区域</text><text class="value">{{ form.regionName }}</text></view>
7   - <view class="row"><text class="label">客户简称</text><text class="value">{{ form.customerShortName }}</text>
  8 + <view class="row"><text class="label">简写名称</text><text class="value">{{ form.customerShortName }}</text>
8 9 </view>
9 10 <view class="row"><text class="label">企业类型</text><text class="value">{{ getDicName('ENTERPRISE_TYPE',
10 11 form.enterpriseType, enterpriseTypeOptions) }}</text></view>
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <uni-list-item class="select-item" :class="form.code ? 'is-filled' : 'is-empty'">
  6 + <template v-slot:body>
  7 + <view class="item-title"><text class="required">*</text><text>编号</text></view>
  8 + </template>
  9 + <template v-slot:footer>
  10 + <view class="serial-number-row">
  11 + <uni-easyinput v-model="form.code" placeholder="自动生成编号" :inputBorder="false" disabled />
  12 + <button class="generate-btn" @click="loadCode">点此生成</button>
  13 + </view>
  14 + </template>
  15 + </uni-list-item>
  16 +
  17 + <uni-list-item title="名称">
  18 + <template v-slot:body>
  19 + <view class="item-title"><text class="required">*</text><text>名称</text></view>
  20 + </template>
  21 + <template v-slot:footer>
  22 + <uni-easyinput v-model="form.name" placeholder="请输入名称" :inputBorder="false" />
  23 + </template>
  24 + </uni-list-item>
  25 +
  26 + <uni-list-item title="联系人">
  27 + <template v-slot:footer>
  28 + <uni-easyinput v-model="form.contact" placeholder="请输入联系人" :inputBorder="false" />
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 + <uni-list-item title="联系电话">
  33 + <template v-slot:footer>
  34 + <uni-easyinput v-model="form.telephone" placeholder="请输入联系电话" :inputBorder="false" />
  35 + </template>
  36 + </uni-list-item>
  37 +
  38 + <uni-list-item title="电子邮箱">
  39 + <template v-slot:footer>
  40 + <uni-easyinput v-model="form.email" placeholder="请输入电子邮箱" :inputBorder="false" />
  41 + </template>
  42 + </uni-list-item>
  43 +
  44 + <uni-list-item title="邮编">
  45 + <template v-slot:footer>
  46 + <uni-easyinput v-model="form.zipCode" placeholder="请输入邮编" :inputBorder="false" />
  47 + </template>
  48 + </uni-list-item>
  49 +
  50 + <uni-list-item title="传真">
  51 + <template v-slot:footer>
  52 + <uni-easyinput v-model="form.fax" placeholder="请输入传真" :inputBorder="false" />
  53 + </template>
  54 + </uni-list-item>
  55 +
  56 + <uni-list-item class="select-item"
  57 + :class="(Array.isArray(form.cityIds) && form.cityIds.length) ? 'is-filled' : 'is-empty'" clickable
  58 + @click="openCitySelector" :rightText="form.cityLabel || '请选择'" showArrow>
  59 + <template v-slot:body>
  60 + <view class="item-title"><text>地区</text></view>
  61 + <CitySelector ref="citySelectorRef" v-model="form.cityIds" @change="onCityChange" />
  62 + </template>
  63 + </uni-list-item>
  64 +
  65 + <uni-list-item title="地址">
  66 + <template v-slot:footer>
  67 + <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
  68 + </template>
  69 + </uni-list-item>
  70 +
  71 + <uni-list-item title="统一社会信用代码">
  72 + <template v-slot:footer>
  73 + <uni-easyinput v-model="form.creditCode" placeholder="请输入统一社会信用代码" :inputBorder="false" />
  74 + </template>
  75 + </uni-list-item>
  76 +
  77 + <uni-list-item title="纳税人识别号">
  78 + <template v-slot:footer>
  79 + <uni-easyinput v-model="form.taxIdentifyNo" placeholder="请输入纳税人识别号" :inputBorder="false" />
  80 + </template>
  81 + </uni-list-item>
  82 +
  83 + <uni-list-item title="开户银行">
  84 + <template v-slot:footer>
  85 + <uni-easyinput v-model="form.bankName" placeholder="请输入开户银行" :inputBorder="false" />
  86 + </template>
  87 + </uni-list-item>
  88 +
  89 + <uni-list-item title="户名">
  90 + <template v-slot:footer>
  91 + <uni-easyinput v-model="form.accountName" placeholder="请输入户名" :inputBorder="false" />
  92 + </template>
  93 + </uni-list-item>
  94 +
  95 + <uni-list-item title="银行账号">
  96 + <template v-slot:footer>
  97 + <uni-easyinput v-model="form.accountNo" placeholder="请输入银行账号" :inputBorder="false" />
  98 + </template>
  99 + </uni-list-item>
  100 +
  101 + <uni-list-item title="备注">
  102 + <template v-slot:footer>
  103 + <uni-easyinput type="textarea" v-model="form.description" placeholder="请输入备注" :inputBorder="false" />
  104 + </template>
  105 + </uni-list-item>
  106 +
  107 + </uni-list>
  108 + </scroll-view>
  109 +
  110 + <view class="footer">
  111 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  112 + </view>
  113 + </view>
  114 +</template>
  115 +
  116 +<script>
  117 +import { createApi } from '@/api/customer.js'
  118 +import { generateCodeApi } from '@/api/base.js'
  119 +import CitySelector from '@/components/city-selector/index.vue'
  120 +import { isEmail } from '@/utils/common.js'
  121 +
  122 +export default {
  123 + name: 'CustomerAdd',
  124 + components: { CitySelector },
  125 + data() {
  126 + return {
  127 + form: {
  128 + code: '',
  129 + name: '',
  130 + contact: '',
  131 + telephone: '',
  132 + email: '',
  133 + zipCode: '',
  134 + fax: '',
  135 + cityIds: [],
  136 + cityLabel: '',
  137 + address: '',
  138 + creditCode: '',
  139 + taxIdentifyNo: '',
  140 + bankName: '',
  141 + accountName: '',
  142 + accountNo: '',
  143 + description: ''
  144 + }
  145 + }
  146 + },
  147 + created() {
  148 + this.loadCode()
  149 + },
  150 + methods: {
  151 + async loadCode() {
  152 + try {
  153 + const res = await generateCodeApi(5)
  154 + this.form.code = (res && res.data) || ''
  155 + } catch (e) {
  156 + this.form.code = ''
  157 + }
  158 + },
  159 + openCitySelector() {
  160 + this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()
  161 + },
  162 + onCityChange(payload) {
  163 + const label = payload && payload.label != null ? payload.label : ''
  164 + this.form.cityLabel = label
  165 + },
  166 + validateRequired() {
  167 + if (!this.form.code) {
  168 + uni.showToast({ title: '请先生成编号', icon: 'none' })
  169 + return false
  170 + }
  171 + if (!this.form.name || !this.form.name.trim()) {
  172 + uni.showToast({ title: '请输入名称', icon: 'none' })
  173 + return false
  174 + }
  175 + if (this.form.email && !isEmail(this.form.email)) {
  176 + uni.showToast({ title: '邮箱地址格式不正确', icon: 'none' })
  177 + return false
  178 + }
  179 + return true
  180 + },
  181 + async onSubmit() {
  182 + if (!this.validateRequired()) return
  183 +
  184 + const { cityIds, cityLabel, ...other } = this.form
  185 + // 取最后一个 ID 作为 city
  186 + const cityId = cityIds && cityIds.length > 0 ? cityIds[cityIds.length - 1] : ''
  187 +
  188 + const payload = {
  189 + ...other,
  190 + cityId
  191 + }
  192 +
  193 + console.log('onSubmit payload', payload)
  194 + try {
  195 + await createApi(payload)
  196 + uni.showToast({ title: '提交成功', icon: 'success' })
  197 + setTimeout(() => { uni.redirectTo({ url: '/pages/customer/index' }) }, 300)
  198 + } catch (e) {
  199 + uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
  200 + }
  201 + }
  202 + }
  203 +}
  204 +</script>
  205 +
  206 +<style lang="scss" scoped>
  207 +.page {
  208 + display: flex;
  209 + flex-direction: column;
  210 + height: 100vh;
  211 +}
  212 +
  213 +.scroll {
  214 + flex: 1;
  215 + padding: 12rpx 0 160rpx;
  216 +}
  217 +
  218 +.footer {
  219 + position: fixed;
  220 + left: 0;
  221 + right: 0;
  222 + bottom: 0;
  223 + padding: 32rpx;
  224 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  225 + background: #fff;
  226 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  227 + z-index: 10;
  228 +
  229 + .btn {
  230 + height: 80rpx;
  231 + line-height: 80rpx;
  232 + border-radius: 12rpx;
  233 + font-size: 32rpx;
  234 + }
  235 +
  236 + .submit {
  237 + background: $theme-primary;
  238 + color: #fff;
  239 + }
  240 +}
  241 +
  242 +::v-deep .uni-list {
  243 + background: transparent;
  244 +
  245 + &-item {
  246 + &__extra-text {
  247 + font-size: 32rpx;
  248 + }
  249 +
  250 + &__content-title {
  251 + font-size: 32rpx;
  252 + color: rgba(0, 0, 0, 0.9);
  253 + }
  254 +
  255 + &__container {
  256 + padding: 32rpx;
  257 +
  258 + .uni-easyinput {
  259 + .is-disabled {
  260 + background-color: transparent !important;
  261 + }
  262 +
  263 + &__placeholder-class {
  264 + font-size: 32rpx;
  265 + color: rgba(0, 0, 0, 0.4);
  266 + }
  267 +
  268 + &__content {
  269 + border: none;
  270 +
  271 + &-input {
  272 + padding-left: 0 !important;
  273 + height: 48rpx;
  274 + line-height: 48rpx;
  275 + font-size: 32rpx;
  276 + }
  277 + }
  278 + }
  279 +
  280 + .item-title,
  281 + .uni-list-item__content {
  282 + flex: none;
  283 + min-height: 48rpx;
  284 + line-height: 48rpx;
  285 + font-size: 32rpx;
  286 + position: relative;
  287 + width: 210rpx;
  288 + margin-right: 32rpx;
  289 + color: rgba(0, 0, 0, 0.9);
  290 + padding-right: 0;
  291 +
  292 + .required {
  293 + color: red;
  294 + position: absolute;
  295 + top: 50%;
  296 + transform: translateY(-50%);
  297 + left: -16rpx;
  298 + }
  299 + }
  300 + }
  301 +
  302 + &.select-item {
  303 + &.is-empty {
  304 + .uni-list-item__extra-text {
  305 + color: rgba(0, 0, 0, 0.4) !important;
  306 + }
  307 + }
  308 +
  309 + &.is-filled {
  310 + .uni-list-item__extra-text {
  311 + color: rgba(0, 0, 0, 0.9) !important;
  312 + }
  313 + }
  314 +
  315 + .serial-number-row {
  316 + display: flex;
  317 + align-items: center;
  318 +
  319 + .generate-btn {
  320 + margin-left: 24rpx;
  321 + height: 64rpx;
  322 + line-height: 64rpx;
  323 + padding: 0 24rpx;
  324 + font-size: 28rpx;
  325 + border-radius: 8rpx;
  326 + background: $theme-primary;
  327 + color: #fff;
  328 + }
  329 + }
  330 + }
  331 + }
  332 +}
  333 +</style>
... ...