Commit 0e6691e68369bf02f1c6d2342110cc48f12309c0

Authored by gesilong
1 parent 12f46663

commit:内贸页面开发

... ... @@ -4,8 +4,8 @@ module.exports = {
4 4 themeColor: '#3d48a3',
5 5
6 6 // baseUrl: 'http://ft.wecando21cn.com/api',
7   - baseUrl: 'http://gjtd.ahcjxc.com:81/api',
8   - // baseUrl: 'http://erp.qgutech.com/api',
  7 + // baseUrl: 'http://gjtd.ahcjxc.com:81/api',
  8 + baseUrl: 'http://erp.qgutech.com/api',
9 9 // baseUrl: 'http://10.9.5.246:8081',
10 10 // 应用信息
11 11 appInfo: {
... ...
... ... @@ -212,6 +212,38 @@
212 212 }
213 213 },
214 214 {
  215 + "path": "pages/domestic_trade/index",
  216 + "style": {
  217 + "navigationBarTitleText": "内贸合同列表",
  218 + "navigationBarBackgroundColor": "#ffffff",
  219 + "navigationBarTextStyle": "black"
  220 + }
  221 + },
  222 + {
  223 + "path": "pages/domestic_trade/add",
  224 + "style": {
  225 + "navigationBarTitleText": "新增内贸合同",
  226 + "navigationBarBackgroundColor": "#ffffff",
  227 + "navigationBarTextStyle": "black"
  228 + }
  229 + },
  230 + {
  231 + "path": "pages/domestic_trade/modify",
  232 + "style": {
  233 + "navigationBarTitleText": "编辑内贸合同",
  234 + "navigationBarBackgroundColor": "#ffffff",
  235 + "navigationBarTextStyle": "black"
  236 + }
  237 + },
  238 + {
  239 + "path": "pages/domestic_trade/detail",
  240 + "style": {
  241 + "navigationBarTitleText": "查看内贸合同",
  242 + "navigationBarBackgroundColor": "#ffffff",
  243 + "navigationBarTextStyle": "black"
  244 + }
  245 + },
  246 + {
215 247 "path": "pages/order_list/index",
216 248 "style": {
217 249 "navigationBarTitleText": "订货单列表",
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <view class="title-header">
  6 + <image class="title-header_icon" src="/static/images/title.png" />
  7 + <span>基本资料</span>
  8 + </view>
  9 +
  10 + <uni-list-item title="单位名称">
  11 + <template v-slot:footer>
  12 + <uni-easyinput v-model="form.companyName" placeholder="请输入单位名称" :inputBorder="false" />
  13 + </template>
  14 + </uni-list-item>
  15 +
  16 + <uni-list-item class="select-item" :class="form.companyNatureName ? 'is-filled' : 'is-empty'" clickable
  17 + @click="openMultiSheet('companyNature')" :rightText="displayLabel('companyNatureName')" showArrow>
  18 + <template v-slot:body>
  19 + <view class="item-title"><text>公司性质</text></view>
  20 + </template>
  21 + </uni-list-item>
  22 + <uni-list-item v-if="showCompanyNatureOther" class="mgb10" title="其他">
  23 + <template v-slot:footer>
  24 + <uni-easyinput v-model="form.companyNatureOther" placeholder="请输入其他公司性质" :inputBorder="false" />
  25 + </template>
  26 + </uni-list-item>
  27 +
  28 + <uni-list-item title="开户行">
  29 + <template v-slot:footer>
  30 + <uni-easyinput v-model="form.bankName" placeholder="请输入开户行" :inputBorder="false" />
  31 + </template>
  32 + </uni-list-item>
  33 +
  34 + <uni-list-item title="账号">
  35 + <template v-slot:footer>
  36 + <uni-easyinput v-model="form.bankAccount" placeholder="请输入账号" :inputBorder="false" />
  37 + </template>
  38 + </uni-list-item>
  39 +
  40 + <uni-list-item class="amount-item">
  41 + <template v-slot:body>
  42 + <view class="item-title"><text>注册资金</text></view>
  43 + </template>
  44 + <template v-slot:footer>
  45 + <view class="amount-row">
  46 + <uni-easyinput type="digit" v-model="form.registeredCapital" placeholder="请输入" :inputBorder="false" />
  47 + <text class="unit">万元</text>
  48 + </view>
  49 + </template>
  50 + </uni-list-item>
  51 +
  52 + <uni-list-item class="amount-item">
  53 + <template v-slot:body>
  54 + <view class="item-title"><text>年营业额</text></view>
  55 + </template>
  56 + <template v-slot:footer>
  57 + <view class="amount-row">
  58 + <uni-easyinput type="digit" v-model="form.annualTurnover" placeholder="请输入" :inputBorder="false" />
  59 + <text class="unit">万元</text>
  60 + </view>
  61 + </template>
  62 + </uni-list-item>
  63 +
  64 + <uni-list-item title="法人代表">
  65 + <template v-slot:footer>
  66 + <uni-easyinput v-model="form.legalRepresentative" placeholder="请输入法人代表" :inputBorder="false" />
  67 + </template>
  68 + </uni-list-item>
  69 +
  70 + <uni-list-item title="公司成立时间">
  71 + <template v-slot:footer>
  72 + <uni-datetime-picker type="date" v-model="form.companyFoundedDate" />
  73 + </template>
  74 + </uni-list-item>
  75 +
  76 + <uni-list-item title="地址">
  77 + <template v-slot:footer>
  78 + <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
  79 + </template>
  80 + </uni-list-item>
  81 +
  82 + <uni-list-item title="业务负责人">
  83 + <template v-slot:footer>
  84 + <uni-easyinput v-model="form.businessOwner" placeholder="请输入业务负责人" :inputBorder="false" />
  85 + </template>
  86 + </uni-list-item>
  87 +
  88 + <uni-list-item title="职务">
  89 + <template v-slot:footer>
  90 + <uni-easyinput v-model="form.position" placeholder="请输入职务" :inputBorder="false" />
  91 + </template>
  92 + </uni-list-item>
  93 +
  94 + <uni-list-item title="电话">
  95 + <template v-slot:footer>
  96 + <uni-easyinput type="number" v-model="form.phone" placeholder="请输入手机号码" :inputBorder="false" />
  97 + </template>
  98 + </uni-list-item>
  99 +
  100 + <uni-list-item title="传真">
  101 + <template v-slot:footer>
  102 + <uni-easyinput v-model="form.fax" placeholder="请输入传真" :inputBorder="false" />
  103 + </template>
  104 + </uni-list-item>
  105 +
  106 + <uni-list-item class="mgb10" title="法人与业务负责人关系">
  107 + <template v-slot:footer>
  108 + <uni-easyinput v-model="form.legalBusinessRelation" placeholder="请输入" :inputBorder="false" />
  109 + </template>
  110 + </uni-list-item>
  111 +
  112 + <view class="title-header">
  113 + <image class="title-header_icon" src="/static/images/title.png" />
  114 + <span>资产状况</span>
  115 + </view>
  116 +
  117 + <uni-list-item title="流动资金">
  118 + <template v-slot:footer>
  119 + <uni-easyinput type="textarea" v-model="form.liquidWorkingCapital" placeholder="1、流动资金 2、购、销结算期限 3、债券债务情况"
  120 + :inputBorder="false" maxlength="2000" />
  121 + </template>
  122 + </uni-list-item>
  123 +
  124 + <uni-list-item class="mgb10" title="固定资产">
  125 + <template v-slot:footer>
  126 + <uni-easyinput type="textarea" v-model="form.fixedAssets" placeholder="1、厂房/办公楼产权、面积 2、主要设备投资规模及产权 3、仓库或货场产权、面积 4、正常库存量"
  127 + :inputBorder="false" maxlength="3000" />
  128 + </template>
  129 + </uni-list-item>
  130 +
  131 + <view class="title-header">
  132 + <image class="title-header_icon" src="/static/images/title.png" />
  133 + <span>生产经营环节风险调查</span>
  134 + </view>
  135 +
  136 + <uni-list-item title="收购情况">
  137 + <template v-slot:footer>
  138 + <uni-easyinput type="textarea" v-model="form.purchaseSituation"
  139 + placeholder="1、主要品种及收购量 2、经营绩效状况(上年度利润,区分铜/铁等) 4、入库流程及入库品名" :inputBorder="false"
  140 + maxlength="3000" />
  141 + </template>
  142 + </uni-list-item>
  143 + <uni-list-item class="select-item" :class="form.purchaseSourceName ? 'is-filled' : 'is-empty'" clickable
  144 + @click="openSheet('purchaseSource')" :rightText="displayLabel('purchaseSourceName')" showArrow>
  145 + <template v-slot:body>
  146 + <view class="item-title"><text>货源来源</text></view>
  147 + </template>
  148 + </uni-list-item>
  149 + <uni-list-item v-if="showPurchaseSourceOther" class="mgb10" title="其他">
  150 + <template v-slot:footer>
  151 + <uni-easyinput v-model="form.purchaseSourceOther" placeholder="请输入其他货源来源" :inputBorder="false" />
  152 + </template>
  153 + </uni-list-item>
  154 +
  155 + <uni-list-item title="生产情况">
  156 + <template v-slot:footer>
  157 + <uni-easyinput type="textarea" v-model="form.productionSituation" placeholder="1、产品介绍 2、产能及对应能耗"
  158 + :inputBorder="false" maxlength="2000" />
  159 + </template>
  160 + </uni-list-item>
  161 +
  162 + <uni-list-item title="销售情况">
  163 + <template v-slot:footer>
  164 + <uni-easyinput type="textarea" v-model="form.salesSituation" placeholder="销售渠道、销量及操作方式、货款回笼方式、结算期限"
  165 + :inputBorder="false" maxlength="2000" />
  166 + </template>
  167 + </uni-list-item>
  168 +
  169 + <uni-list-item class="select-item" :class="form.preferentialPolicyName ? 'is-filled' : 'is-empty'" clickable
  170 + @click="openSheet('preferentialPolicy')" :rightText="displayLabel('preferentialPolicyName')" showArrow>
  171 + <template v-slot:body>
  172 + <view class="item-title"><text>是否享受优惠政策</text></view>
  173 + </template>
  174 + </uni-list-item>
  175 + <uni-list-item class="mgb10" title="详细说明">
  176 + <template v-slot:footer>
  177 + <uni-easyinput type="textarea" v-model="form.preferentialPolicyDetail" placeholder="请输入详细说明"
  178 + :inputBorder="false" maxlength="2000" />
  179 + </template>
  180 + </uni-list-item>
  181 +
  182 + <uni-list-item class="select-item" :class="form.punishmentRecordName ? 'is-filled' : 'is-empty'" clickable
  183 + @click="openSheet('punishmentRecord')" :rightText="displayLabel('punishmentRecordName')" showArrow>
  184 + <template v-slot:body>
  185 + <view class="item-title"><text>是否有被处罚记录</text></view>
  186 + </template>
  187 + </uni-list-item>
  188 + <uni-list-item class="mgb10" title="实际经营范围与法定经营范围是否相符">
  189 + <template v-slot:footer>
  190 + <uni-easyinput type="textarea" v-model="form.scopeMatch" placeholder="请输入" :inputBorder="false"
  191 + maxlength="2000" />
  192 + </template>
  193 + </uni-list-item>
  194 +
  195 + <uni-list-item class="select-item" :class="form.futuresInvestName ? 'is-filled' : 'is-empty'" clickable
  196 + @click="openSheet('futuresInvest')" :rightText="displayLabel('futuresInvestName')" showArrow>
  197 + <template v-slot:body>
  198 + <view class="item-title"><text>是否投资期货</text></view>
  199 + </template>
  200 + </uni-list-item>
  201 +
  202 + <uni-list-item class="select-item" :class="form.investNatureName ? 'is-filled' : 'is-empty'" clickable
  203 + @click="openSheet('investNature')" :rightText="displayLabel('investNatureName')" showArrow>
  204 + <template v-slot:body>
  205 + <view class="item-title"><text>投资性质</text></view>
  206 + </template>
  207 + </uni-list-item>
  208 +
  209 + <uni-list-item class="mgb10" title="上年度期货盈亏">
  210 + <template v-slot:footer>
  211 + <uni-easyinput v-model="form.lastYearFuturesProfitLoss" placeholder="请输入" :inputBorder="false" />
  212 + </template>
  213 + </uni-list-item>
  214 +
  215 + <view class="title-header">
  216 + <image class="title-header_icon" src="/static/images/title.png" />
  217 + <span>与我司的合作状况</span>
  218 + </view>
  219 +
  220 + <uni-list-item class="amount-item">
  221 + <template v-slot:body>
  222 + <view class="item-title"><text>合作年限</text></view>
  223 + </template>
  224 + <template v-slot:footer>
  225 + <view class="amount-row">
  226 + <text class="prefix">从</text>
  227 + <uni-easyinput type="digit" v-model="form.cooperationStartYear" placeholder="年份" :inputBorder="false" />
  228 + <text class="suffix">年开始合作</text>
  229 + </view>
  230 + </template>
  231 + </uni-list-item>
  232 +
  233 + <uni-list-item title="主要操作方式">
  234 + <template v-slot:footer>
  235 + <uni-easyinput type="textarea" v-model="form.mainOperationMode" placeholder="请输入"
  236 + :inputBorder="false" maxlength="2000" />
  237 + </template>
  238 + </uni-list-item>
  239 +
  240 + <uni-list-item class="select-item" :class="form.badRecordPlanFailName ? 'is-filled' : 'is-empty'" clickable
  241 + @click="openSheet('badRecordPlanFail')" :rightText="displayLabel('badRecordPlanFailName')" showArrow>
  242 + <template v-slot:body>
  243 + <view class="item-title"><text>是否有计划落空的不良记录</text></view>
  244 + </template>
  245 + </uni-list-item>
  246 + <uni-list-item class="select-item" :class="form.planNotFulfilledName ? 'is-filled' : 'is-empty'" clickable
  247 + @click="openSheet('planNotFulfilled')" :rightText="displayLabel('planNotFulfilledName')" showArrow>
  248 + <template v-slot:body>
  249 + <view class="item-title"><text>是否有计划履行不到位现象(时间、数量等)</text></view>
  250 + </template>
  251 + </uni-list-item>
  252 +
  253 + <uni-list-item title="操作规范性">
  254 + <template v-slot:footer>
  255 + <uni-easyinput type="textarea" v-model="form.operationNorms" placeholder="1、进销账务如何处理 2、开票品名与出库单品名是否一致 3、出库流程是否规范 4、运输发票情况"
  256 + :inputBorder="false" maxlength="3000" />
  257 + </template>
  258 + </uni-list-item>
  259 +
  260 + <uni-list-item title="常见料质问题">
  261 + <template v-slot:footer>
  262 + <uni-easyinput type="textarea" v-model="form.commonMaterialIssues" placeholder="请输入"
  263 + :inputBorder="false" maxlength="2000" />
  264 + </template>
  265 + </uni-list-item>
  266 +
  267 + <uni-list-item class="mgb10" title="合作中的其他问题">
  268 + <template v-slot:footer>
  269 + <uni-easyinput type="textarea" v-model="form.otherCooperationIssues" placeholder="请输入"
  270 + :inputBorder="false" maxlength="2000" />
  271 + </template>
  272 + </uni-list-item>
  273 +
  274 + <view class="title-header">
  275 + <image class="title-header_icon" src="/static/images/title.png" />
  276 + <span>其他</span>
  277 + </view>
  278 +
  279 + <uni-list-item title="创建日期">
  280 + <template v-slot:footer>
  281 + <uni-datetime-picker type="date" v-model="form.createDate" />
  282 + </template>
  283 + </uni-list-item>
  284 +
  285 + <uni-list-item title="评审时间">
  286 + <template v-slot:footer>
  287 + <uni-datetime-picker type="date" v-model="form.reviewDate" />
  288 + </template>
  289 + </uni-list-item>
  290 +
  291 + <uni-list-item class="mgb10" title="附件">
  292 + <template v-slot:footer>
  293 + <view class="attach-box">
  294 + <view v-for="(f, idx) in form.attachments" :key="idx" class="attach-row">
  295 + <FileUpload :value="f" @input="onAttachmentInput(idx, $event)" />
  296 + <text class="attach-del" @click.stop="removeAttachment(idx)">删除</text>
  297 + </view>
  298 + <view class="attach-row">
  299 + <FileUpload :value="newAttachment" @input="onAddAttachment" />
  300 + </view>
  301 + </view>
  302 + </template>
  303 + </uni-list-item>
  304 + </uni-list>
  305 + </scroll-view>
  306 +
  307 + <view class="footer">
  308 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '提交中...' : '提交' }}</button>
  309 + </view>
  310 +
  311 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  312 + @confirm="onSheetConfirm" />
  313 + <MultiSelectSheet :visible.sync="multiSheet.visible" :title="multiSheet.title" :options="multiSheet.options"
  314 + v-model="multiSheet.value" @confirm="onMultiSheetConfirm" />
  315 + </view>
  316 +</template>
  317 +
  318 +<script>
  319 +import FileUpload from '@/components/file-upload/index.vue'
  320 +import SingleSelectSheet from '@/components/single-select/index.vue'
  321 +import MultiSelectSheet from '@/components/multi-select/index.vue'
  322 +
  323 +export default {
  324 + name: 'DomesticTradeAdd',
  325 + components: { FileUpload, SingleSelectSheet, MultiSelectSheet },
  326 + data() {
  327 + return {
  328 + submitting: false,
  329 + newAttachment: { id: '', name: '' },
  330 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  331 + multiSheet: { visible: false, title: '', options: [], field: '', value: '' },
  332 + yesNoOptions: [
  333 + { label: '是', value: 'YES' },
  334 + { label: '否', value: 'NO' }
  335 + ],
  336 + investNatureOptions: [
  337 + { label: '投机', value: 'SPECULATION' },
  338 + { label: '保值', value: 'HEDGE' },
  339 + { label: '保值为主投机为辅', value: 'HEDGE_MAIN' }
  340 + ],
  341 + companyNatureOptions: [
  342 + { label: '回收公司', value: 'RECYCLE' },
  343 + { label: '贸易公司', value: 'TRADE' },
  344 + { label: '进口拆解', value: 'IMPORT_DISMANTLE' },
  345 + { label: '工业制造', value: 'INDUSTRY_MANUFACTURE' },
  346 + { label: '福利企业', value: 'WELFARE_ENTERPRISE' },
  347 + { label: '其他', value: 'OTHER' }
  348 + ],
  349 + purchaseSourceOptions: [
  350 + { label: '国外进口', value: 'IMPORT' },
  351 + { label: '本企业报废', value: 'SELF_SCRAP' },
  352 + { label: '零散收购', value: 'SCATTERED' },
  353 + { label: '其他', value: 'OTHER' }
  354 + ],
  355 + form: {
  356 + companyName: '',
  357 + companyNature: '',
  358 + companyNatureName: '',
  359 + companyNatureOther: '',
  360 + bankName: '',
  361 + bankAccount: '',
  362 + registeredCapital: '',
  363 + annualTurnover: '',
  364 + legalRepresentative: '',
  365 + companyFoundedDate: '',
  366 + address: '',
  367 + businessOwner: '',
  368 + position: '',
  369 + phone: '',
  370 + fax: '',
  371 + legalBusinessRelation: '',
  372 + liquidWorkingCapital: '',
  373 + fixedAssets: '',
  374 + purchaseSituation: '',
  375 + purchaseSource: '',
  376 + purchaseSourceName: '',
  377 + purchaseSourceOther: '',
  378 + productionSituation: '',
  379 + salesSituation: '',
  380 + preferentialPolicy: '',
  381 + preferentialPolicyName: '',
  382 + preferentialPolicyDetail: '',
  383 + punishmentRecord: '',
  384 + punishmentRecordName: '',
  385 + scopeMatch: '',
  386 + futuresInvest: '',
  387 + futuresInvestName: '',
  388 + investNature: '',
  389 + investNatureName: '',
  390 + lastYearFuturesProfitLoss: '',
  391 + cooperationStartYear: '',
  392 + mainOperationMode: '',
  393 + badRecordPlanFail: '',
  394 + badRecordPlanFailName: '',
  395 + planNotFulfilled: '',
  396 + planNotFulfilledName: '',
  397 + operationNorms: '',
  398 + commonMaterialIssues: '',
  399 + otherCooperationIssues: '',
  400 + createDate: '',
  401 + reviewDate: '',
  402 + attachments: []
  403 + }
  404 + }
  405 + },
  406 + computed: {
  407 + showCompanyNatureOther() {
  408 + const v = String(this.form.companyNature || '')
  409 + return v.split(',').includes('OTHER')
  410 + },
  411 + showPurchaseSourceOther() {
  412 + return this.form.purchaseSource === 'OTHER'
  413 + }
  414 + },
  415 + created() {
  416 + this.form.createDate = this.formatDate(new Date())
  417 + },
  418 + methods: {
  419 + displayLabel(field) {
  420 + const m = this.form || {}
  421 + const map = {
  422 + companyNatureName: '请选择公司性质',
  423 + purchaseSourceName: '请选择货源来源',
  424 + preferentialPolicyName: '请选择',
  425 + punishmentRecordName: '请选择',
  426 + futuresInvestName: '请选择',
  427 + investNatureName: '请选择',
  428 + badRecordPlanFailName: '请选择',
  429 + planNotFulfilledName: '请选择'
  430 + }
  431 + const val = m[field]
  432 + return val ? String(val) : map[field]
  433 + },
  434 + openSheet(field) {
  435 + const map = {
  436 + purchaseSource: { title: '货源来源', options: this.purchaseSourceOptions, valueField: 'purchaseSource', nameField: 'purchaseSourceName' },
  437 + preferentialPolicy: { title: '是否享受优惠政策', options: this.yesNoOptions, valueField: 'preferentialPolicy', nameField: 'preferentialPolicyName' },
  438 + punishmentRecord: { title: '是否有被处罚记录', options: this.yesNoOptions, valueField: 'punishmentRecord', nameField: 'punishmentRecordName' },
  439 + futuresInvest: { title: '是否投资期货', options: this.yesNoOptions, valueField: 'futuresInvest', nameField: 'futuresInvestName' },
  440 + investNature: { title: '投资性质', options: this.investNatureOptions, valueField: 'investNature', nameField: 'investNatureName' },
  441 + badRecordPlanFail: { title: '是否有计划落空的不良记录', options: this.yesNoOptions, valueField: 'badRecordPlanFail', nameField: 'badRecordPlanFailName' },
  442 + planNotFulfilled: { title: '是否有计划履行不到位现象', options: this.yesNoOptions, valueField: 'planNotFulfilled', nameField: 'planNotFulfilledName' }
  443 + }
  444 + const cfg = map[field]
  445 + if (!cfg) return
  446 + const current = this.form[cfg.valueField]
  447 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  448 + this.sheet = {
  449 + ...this.sheet,
  450 + visible: true,
  451 + title: cfg.title,
  452 + options: cfg.options || [],
  453 + field,
  454 + value: match ? match.value : (current || '')
  455 + }
  456 + },
  457 + openMultiSheet(field) {
  458 + if (field !== 'companyNature') return
  459 + this.multiSheet = {
  460 + ...this.multiSheet,
  461 + visible: true,
  462 + title: '公司性质',
  463 + options: this.companyNatureOptions || [],
  464 + field,
  465 + value: this.form.companyNature || ''
  466 + }
  467 + },
  468 + onSheetConfirm({ value, label }) {
  469 + const field = this.sheet.field
  470 + if (field === 'purchaseSource') {
  471 + this.form.purchaseSource = value || ''
  472 + this.form.purchaseSourceName = label || ''
  473 + if (this.form.purchaseSource !== 'OTHER') this.form.purchaseSourceOther = ''
  474 + } else if (field === 'preferentialPolicy') {
  475 + this.form.preferentialPolicy = value || ''
  476 + this.form.preferentialPolicyName = label || ''
  477 + } else if (field === 'punishmentRecord') {
  478 + this.form.punishmentRecord = value || ''
  479 + this.form.punishmentRecordName = label || ''
  480 + } else if (field === 'futuresInvest') {
  481 + this.form.futuresInvest = value || ''
  482 + this.form.futuresInvestName = label || ''
  483 + } else if (field === 'investNature') {
  484 + this.form.investNature = value || ''
  485 + this.form.investNatureName = label || ''
  486 + } else if (field === 'badRecordPlanFail') {
  487 + this.form.badRecordPlanFail = value || ''
  488 + this.form.badRecordPlanFailName = label || ''
  489 + } else if (field === 'planNotFulfilled') {
  490 + this.form.planNotFulfilled = value || ''
  491 + this.form.planNotFulfilledName = label || ''
  492 + }
  493 + this.sheet.visible = false
  494 + },
  495 + onMultiSheetConfirm({ value, label }) {
  496 + const field = this.multiSheet.field
  497 + if (field === 'companyNature') {
  498 + const normalized = this.normalizeCompanyNature(value)
  499 + this.form.companyNature = normalized.value
  500 + this.form.companyNatureName = normalized.label
  501 + if (!this.showCompanyNatureOther) this.form.companyNatureOther = ''
  502 + }
  503 + this.multiSheet.visible = false
  504 + },
  505 + normalizeCompanyNature(valueStr) {
  506 + const selected = (valueStr ? String(valueStr).split(',').filter(Boolean) : [])
  507 + const group = ['IMPORT_DISMANTLE', 'INDUSTRY_MANUFACTURE', 'WELFARE_ENTERPRISE']
  508 + const groupSelected = selected.filter(v => group.includes(v))
  509 + let finalSelected = selected.slice(0)
  510 + if (groupSelected.length > 1) {
  511 + const keep = groupSelected[0]
  512 + finalSelected = finalSelected.filter(v => !group.includes(v) || v === keep)
  513 + }
  514 + const orderedValues = []
  515 + const orderedLabels = []
  516 + ;(this.companyNatureOptions || []).forEach(opt => {
  517 + const v = opt && opt.value != null ? String(opt.value) : ''
  518 + if (v && finalSelected.includes(v)) {
  519 + orderedValues.push(v)
  520 + orderedLabels.push(opt.label != null ? String(opt.label) : '')
  521 + }
  522 + })
  523 + return { value: orderedValues.join(','), label: orderedLabels.join(',') }
  524 + },
  525 + removeAttachment(idx) {
  526 + const list = Array.isArray(this.form.attachments) ? this.form.attachments.slice(0) : []
  527 + list.splice(idx, 1)
  528 + this.form.attachments = list
  529 + },
  530 + onAddAttachment(val) {
  531 + const payload = val || { id: '', name: '' }
  532 + if (!payload.id) return
  533 + const list = Array.isArray(this.form.attachments) ? this.form.attachments.slice(0) : []
  534 + list.push(payload)
  535 + this.form.attachments = list
  536 + this.newAttachment = { id: '', name: '' }
  537 + },
  538 + onAttachmentInput(idx, val) {
  539 + const list = Array.isArray(this.form.attachments) ? this.form.attachments.slice(0) : []
  540 + list[idx] = val || { id: '', name: '' }
  541 + this.form.attachments = list
  542 + },
  543 + validate() {
  544 + const phone = String(this.form.phone || '').trim()
  545 + if (phone && !/^1\d{10}$/.test(phone)) {
  546 + uni.showToast({ title: '电话请输入11位手机号', icon: 'none' })
  547 + return false
  548 + }
  549 + const year = String(this.form.cooperationStartYear || '').trim()
  550 + if (year && !/^\d{4}$/.test(year)) {
  551 + uni.showToast({ title: '合作年限请填写4位年份', icon: 'none' })
  552 + return false
  553 + }
  554 + return true
  555 + },
  556 + buildPayload() {
  557 + const payload = { ...this.form }
  558 + if (!this.showCompanyNatureOther) payload.companyNatureOther = ''
  559 + if (payload.purchaseSource !== 'OTHER') payload.purchaseSourceOther = ''
  560 + delete payload.companyNatureName
  561 + delete payload.purchaseSourceName
  562 + delete payload.preferentialPolicyName
  563 + delete payload.punishmentRecordName
  564 + delete payload.futuresInvestName
  565 + delete payload.investNatureName
  566 + delete payload.badRecordPlanFailName
  567 + delete payload.planNotFulfilledName
  568 + payload.attachments = (Array.isArray(payload.attachments) ? payload.attachments : []).filter(it => it && it.id)
  569 + return payload
  570 + },
  571 + async onSubmit() {
  572 + if (this.submitting) return
  573 + if (!this.validate()) return
  574 + this.submitting = true
  575 + const payload = this.buildPayload()
  576 + try {
  577 + await this.mockCreate(payload)
  578 + uni.showToast({ title: '提交成功', icon: 'success' })
  579 + setTimeout(() => { uni.navigateBack() }, 300)
  580 + } catch (e) {
  581 + uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
  582 + } finally {
  583 + this.submitting = false
  584 + }
  585 + },
  586 + mockCreate() {
  587 + return new Promise(resolve => setTimeout(resolve, 400))
  588 + },
  589 + formatDate(d) {
  590 + const y = d.getFullYear()
  591 + const m = String(d.getMonth() + 1).padStart(2, '0')
  592 + const da = String(d.getDate()).padStart(2, '0')
  593 + return `${y}-${m}-${da}`
  594 + }
  595 + }
  596 +}
  597 +</script>
  598 +
  599 +<style lang="scss" scoped>
  600 +.page {
  601 + display: flex;
  602 + flex-direction: column;
  603 + height: 100%;
  604 +}
  605 +
  606 +.scroll {
  607 + flex: 1;
  608 + padding: 12rpx 0 160rpx;
  609 +}
  610 +
  611 +.footer {
  612 + position: fixed;
  613 + left: 0;
  614 + right: 0;
  615 + bottom: 0;
  616 + padding: 32rpx;
  617 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  618 + background: #fff;
  619 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  620 + z-index: 10;
  621 +
  622 + .btn {
  623 + height: 80rpx;
  624 + line-height: 80rpx;
  625 + border-radius: 12rpx;
  626 + font-size: 32rpx;
  627 + }
  628 +
  629 + .submit {
  630 + background: $theme-primary;
  631 + color: #fff;
  632 + }
  633 +}
  634 +
  635 +.title-header {
  636 + display: flex;
  637 + align-items: center;
  638 + padding: 24rpx 32rpx 12rpx;
  639 + background-color: #ffffff;
  640 + .title-header_icon {
  641 + width: 36rpx;
  642 + height: 36rpx;
  643 + margin-right: 12rpx;
  644 + }
  645 +
  646 + span {
  647 + font-size: 34rpx;
  648 + font-weight: 600;
  649 + color: rgba(0, 0, 0, 0.9);
  650 + }
  651 +}
  652 +
  653 +.mgb10 {
  654 + margin-bottom: 20rpx;
  655 +}
  656 +
  657 +.amount-row {
  658 + display: flex;
  659 + align-items: center;
  660 + gap: 12rpx;
  661 +
  662 + .unit, .prefix, .suffix {
  663 + font-size: 28rpx;
  664 + color: rgba(0, 0, 0, 0.6);
  665 + white-space: nowrap;
  666 + }
  667 +}
  668 +
  669 +.attach-box {
  670 + display: flex;
  671 + flex-direction: column;
  672 + align-items: flex-end;
  673 + gap: 16rpx;
  674 + width: 100%;
  675 +}
  676 +
  677 +.attach-row {
  678 + width: 100%;
  679 + display: flex;
  680 + justify-content: flex-end;
  681 + align-items: center;
  682 + gap: 20rpx;
  683 +}
  684 +
  685 +.attach-del {
  686 + font-size: 28rpx;
  687 + color: #D54941;
  688 +}
  689 +
  690 +::v-deep .uni-list {
  691 + .uni-easyinput {
  692 + display: flex;
  693 +
  694 + .uni-input-input {
  695 + color: rgba(0, 0, 0, 0.9);
  696 + }
  697 + }
  698 +
  699 + .uni-input-placeholder {
  700 + z-index: 1;
  701 + }
  702 +
  703 + .uni-input-input {
  704 + background-color: #ffffff;
  705 + }
  706 +
  707 + background: transparent;
  708 +
  709 + &-item {
  710 + &__extra-text {
  711 + font-size: 32rpx;
  712 + }
  713 +
  714 + &__content-title {
  715 + font-size: 32rpx;
  716 + color: rgba(0, 0, 0, 0.9);
  717 + }
  718 +
  719 + &__container {
  720 + padding: 32rpx;
  721 +
  722 + .uni-easyinput {
  723 + &__placeholder-class {
  724 + font-size: 32rpx;
  725 + color: rgba(0, 0, 0, 0.4);
  726 + }
  727 +
  728 + &__content {
  729 + border: none;
  730 + background-color: #ffffff !important;
  731 +
  732 + &-input {
  733 + padding-left: 0 !important;
  734 + height: 48rpx;
  735 + line-height: 48rpx;
  736 + font-size: 32rpx;
  737 + }
  738 +
  739 + .content-clear-icon {
  740 + font-size: 44rpx !important;
  741 + }
  742 + }
  743 + }
  744 +
  745 + .item-title,
  746 + .uni-list-item__content {
  747 + flex: none;
  748 + min-height: 48rpx;
  749 + line-height: 48rpx;
  750 + font-size: 32rpx;
  751 + position: relative;
  752 + width: 210rpx;
  753 + margin-right: 32rpx;
  754 + color: rgba(0, 0, 0, 0.9);
  755 +
  756 + .required {
  757 + color: red;
  758 + position: absolute;
  759 + top: 50%;
  760 + transform: translateY(-50%);
  761 + left: -16rpx;
  762 + }
  763 + }
  764 + }
  765 +
  766 + &.select-item {
  767 + &.is-empty {
  768 + .uni-list-item__extra-text {
  769 + color: rgba(0, 0, 0, 0.4) !important;
  770 + }
  771 + }
  772 +
  773 + &.is-filled {
  774 + .uni-list-item__extra-text {
  775 + color: rgba(0, 0, 0, 0.9) !important;
  776 + }
  777 + }
  778 + }
  779 +
  780 + &.mgb10 {
  781 + margin-bottom: 20rpx;
  782 + }
  783 + }
  784 +}
  785 +</style>
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="detail-page">
  5 + <view class="section">
  6 + <text class="row company">{{ safeText(form.companyName) }}</text>
  7 + <view class="row"><text class="label">公司性质</text><text class="value">{{ safeText(companyNatureName) }}</text></view>
  8 + <view v-if="showCompanyNatureOther" class="row"><text class="label">其他</text><text class="value">{{ safeText(form.companyNatureOther) }}</text></view>
  9 + <view class="row"><text class="label">开户行</text><text class="value">{{ safeText(form.bankName) }}</text></view>
  10 + <view class="row"><text class="label">账号</text><text class="value">{{ safeText(form.bankAccount) }}</text></view>
  11 + <view class="row"><text class="label">注册资金(万元)</text><text class="value">{{ safeText(form.registeredCapital) }}</text></view>
  12 + <view class="row"><text class="label">年营业额(万元)</text><text class="value">{{ safeText(form.annualTurnover) }}</text></view>
  13 + <view class="row"><text class="label">法人代表</text><text class="value">{{ safeText(form.legalRepresentative) }}</text></view>
  14 + <view class="row"><text class="label">公司成立时间</text><text class="value">{{ safeText(form.companyFoundedDate) }}</text></view>
  15 + <view class="row"><text class="label">地址</text><text class="value">{{ safeText(form.address) }}</text></view>
  16 + <view class="row"><text class="label">业务负责人</text><text class="value">{{ safeText(form.businessOwner) }}</text></view>
  17 + <view class="row"><text class="label">职务</text><text class="value">{{ safeText(form.position) }}</text></view>
  18 + <view class="row"><text class="label">电话</text><text class="value">{{ safeText(form.phone) }}</text></view>
  19 + <view class="row"><text class="label">传真</text><text class="value">{{ safeText(form.fax) }}</text></view>
  20 + <view class="row"><text class="label">法人与业务负责人关系</text><text class="value">{{ safeText(form.legalBusinessRelation) }}</text></view>
  21 + </view>
  22 +
  23 + <view class="title-header">
  24 + <image class="title-header_icon" src="/static/images/title.png" />
  25 + <span>资产状况</span>
  26 + </view>
  27 + <view class="section">
  28 + <view class="row"><text class="label">流动资金</text><text class="value pre">{{ safeText(form.liquidWorkingCapital) }}</text></view>
  29 + <view class="row"><text class="label">固定资产</text><text class="value pre">{{ safeText(form.fixedAssets) }}</text></view>
  30 + </view>
  31 +
  32 + <view class="title-header">
  33 + <image class="title-header_icon" src="/static/images/title.png" />
  34 + <span>生产经营环节风险调查</span>
  35 + </view>
  36 + <view class="section">
  37 + <view class="row"><text class="label">收购情况</text><text class="value pre">{{ safeText(form.purchaseSituation) }}</text></view>
  38 + <view class="row"><text class="label">货源来源</text><text class="value">{{ safeText(purchaseSourceName) }}</text></view>
  39 + <view v-if="showPurchaseSourceOther" class="row"><text class="label">其他</text><text class="value">{{ safeText(form.purchaseSourceOther) }}</text></view>
  40 + <view class="row"><text class="label">生产情况</text><text class="value pre">{{ safeText(form.productionSituation) }}</text></view>
  41 + <view class="row"><text class="label">销售情况</text><text class="value pre">{{ safeText(form.salesSituation) }}</text></view>
  42 + <view class="row"><text class="label">是否享受优惠政策</text><text class="value">{{ safeText(preferentialPolicyName) }}</text></view>
  43 + <view class="row"><text class="label">详细说明</text><text class="value pre">{{ safeText(form.preferentialPolicyDetail) }}</text></view>
  44 + <view class="row"><text class="label">是否有被处罚记录</text><text class="value">{{ safeText(punishmentRecordName) }}</text></view>
  45 + <view class="row"><text class="label">经营范围是否相符</text><text class="value pre">{{ safeText(form.scopeMatch) }}</text></view>
  46 + <view class="row"><text class="label">是否投资期货</text><text class="value">{{ safeText(futuresInvestName) }}</text></view>
  47 + <view class="row"><text class="label">投资性质</text><text class="value">{{ safeText(investNatureName) }}</text></view>
  48 + <view class="row"><text class="label">上年度期货盈亏</text><text class="value">{{ safeText(form.lastYearFuturesProfitLoss) }}</text></view>
  49 + </view>
  50 +
  51 + <view class="title-header">
  52 + <image class="title-header_icon" src="/static/images/title.png" />
  53 + <span>与我司的合作状况</span>
  54 + </view>
  55 + <view class="section">
  56 + <view class="row"><text class="label">合作年限</text><text class="value">{{ cooperationYearText }}</text></view>
  57 + <view class="row"><text class="label">主要操作方式</text><text class="value pre">{{ safeText(form.mainOperationMode) }}</text></view>
  58 + <view class="row"><text class="label">计划落空不良记录</text><text class="value">{{ safeText(badRecordPlanFailName) }}</text></view>
  59 + <view class="row"><text class="label">履行不到位现象</text><text class="value">{{ safeText(planNotFulfilledName) }}</text></view>
  60 + <view class="row"><text class="label">操作规范性</text><text class="value pre">{{ safeText(form.operationNorms) }}</text></view>
  61 + <view class="row"><text class="label">常见料质问题</text><text class="value pre">{{ safeText(form.commonMaterialIssues) }}</text></view>
  62 + <view class="row"><text class="label">合作中的其他问题</text><text class="value pre">{{ safeText(form.otherCooperationIssues) }}</text></view>
  63 + </view>
  64 +
  65 + <view class="title-header">
  66 + <image class="title-header_icon" src="/static/images/title.png" />
  67 + <span>其他</span>
  68 + </view>
  69 + <view class="section">
  70 + <view class="row"><text class="label">创建日期</text><text class="value">{{ safeText(form.createDate) }}</text></view>
  71 + <view class="row"><text class="label">评审时间</text><text class="value">{{ safeText(form.reviewDate) }}</text></view>
  72 + <view class="row">
  73 + <text class="label">附件</text>
  74 + <view class="value">
  75 + <view v-if="!attachments.length" class="value">-</view>
  76 + <view v-for="item in attachments" :key="item.id || item.name" class="file-item" @click="onDownload(item)">
  77 + <text class="value act">{{ item.name }}</text>
  78 + </view>
  79 + </view>
  80 + </view>
  81 + </view>
  82 + </view>
  83 + </scroll-view>
  84 + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" />
  85 + </view>
  86 +</template>
  87 +
  88 +<script>
  89 +import { downloadFile } from '@/utils/downloadFile.js'
  90 +import DetailButtons from '@/components/detail-buttons/index.vue'
  91 +
  92 +export default {
  93 + name: 'DomesticTradeDetail',
  94 + components: {
  95 + DetailButtons
  96 + },
  97 + data() {
  98 + return {
  99 + id: '',
  100 + loading: false,
  101 + form: {},
  102 + buttons: [{
  103 + text: '编辑',
  104 + visible: true,
  105 + variant: 'outline',
  106 + event: 'edit',
  107 + }]
  108 + }
  109 + },
  110 + computed: {
  111 + displayButtons() {
  112 + return [
  113 + { ...this.buttons[0], visible: true },
  114 + ]
  115 + },
  116 + companyNatureOptions() {
  117 + return [
  118 + { label: '回收公司', value: 'RECYCLE' },
  119 + { label: '贸易公司', value: 'TRADE' },
  120 + { label: '进口拆解', value: 'IMPORT_DISMANTLE' },
  121 + { label: '工业制造', value: 'INDUSTRY_MANUFACTURE' },
  122 + { label: '福利企业', value: 'WELFARE_ENTERPRISE' },
  123 + { label: '其他', value: 'OTHER' }
  124 + ]
  125 + },
  126 + purchaseSourceOptions() {
  127 + return [
  128 + { label: '国外进口', value: 'IMPORT' },
  129 + { label: '本企业报废', value: 'SELF_SCRAP' },
  130 + { label: '零散收购', value: 'SCATTERED' },
  131 + { label: '其他', value: 'OTHER' }
  132 + ]
  133 + },
  134 + yesNoOptions() {
  135 + return [
  136 + { label: '是', value: 'YES' },
  137 + { label: '否', value: 'NO' }
  138 + ]
  139 + },
  140 + investNatureOptions() {
  141 + return [
  142 + { label: '投机', value: 'SPECULATION' },
  143 + { label: '保值', value: 'HEDGE' },
  144 + { label: '保值为主投机为辅', value: 'HEDGE_MAIN' }
  145 + ]
  146 + },
  147 + attachments() {
  148 + const arr = this.form && Array.isArray(this.form.attachments) ? this.form.attachments : []
  149 + return arr.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  150 + },
  151 + showCompanyNatureOther() {
  152 + const v = String((this.form && this.form.companyNature) || '')
  153 + return v.split(',').includes('OTHER')
  154 + },
  155 + showPurchaseSourceOther() {
  156 + return String((this.form && this.form.purchaseSource) || '') === 'OTHER'
  157 + },
  158 + companyNatureName() {
  159 + return this.safeText(this.form.companyNatureName) || this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  160 + },
  161 + purchaseSourceName() {
  162 + return this.safeText(this.form.purchaseSourceName) || this.labelOf(this.purchaseSourceOptions, this.form.purchaseSource)
  163 + },
  164 + preferentialPolicyName() {
  165 + return this.safeText(this.form.preferentialPolicyName) || this.labelOf(this.yesNoOptions, this.form.preferentialPolicy)
  166 + },
  167 + punishmentRecordName() {
  168 + return this.safeText(this.form.punishmentRecordName) || this.labelOf(this.yesNoOptions, this.form.punishmentRecord)
  169 + },
  170 + futuresInvestName() {
  171 + return this.safeText(this.form.futuresInvestName) || this.labelOf(this.yesNoOptions, this.form.futuresInvest)
  172 + },
  173 + investNatureName() {
  174 + return this.safeText(this.form.investNatureName) || this.labelOf(this.investNatureOptions, this.form.investNature)
  175 + },
  176 + badRecordPlanFailName() {
  177 + return this.safeText(this.form.badRecordPlanFailName) || this.labelOf(this.yesNoOptions, this.form.badRecordPlanFail)
  178 + },
  179 + planNotFulfilledName() {
  180 + return this.safeText(this.form.planNotFulfilledName) || this.labelOf(this.yesNoOptions, this.form.planNotFulfilled)
  181 + },
  182 + cooperationYearText() {
  183 + const y = this.safeText(this.form.cooperationStartYear)
  184 + return y ? `从${y}年开始合作` : '-'
  185 + }
  186 + },
  187 + onShow() {
  188 + const options = (this.$route && this.$route.query) ? this.$route.query : {}
  189 + const id = options && options.id ? String(options.id) : ''
  190 + this.id = id
  191 + this.loadDetail()
  192 + },
  193 + methods: {
  194 + handleButtonClick(btn) {
  195 + if (!btn || btn.disabled) return
  196 + if (typeof btn.onClick === 'function') return btn.onClick(this.detail, btn.params)
  197 + const e = btn.event || ''
  198 + if (e === 'edit') return this.onEdit(btn && btn.params)
  199 + },
  200 + onEdit(params) {
  201 + uni.navigateTo({ url: '/pages/domestic_trade/modify?id=' + this.id })
  202 + },
  203 + safeText(v) {
  204 + const s = v == null ? '' : String(v)
  205 + return s.trim() ? s : ''
  206 + },
  207 + labelOf(options, value) {
  208 + const v = value == null ? '' : String(value)
  209 + if (!v) return '-'
  210 + const found = (options || []).find(o => String(o.value) === v)
  211 + return found ? String(found.label) : v
  212 + },
  213 + labelsOf(options, csv) {
  214 + const v = csv == null ? '' : String(csv)
  215 + if (!v) return '-'
  216 + const parts = v.split(',').filter(Boolean)
  217 + if (!parts.length) return '-'
  218 + const labels = []
  219 + ;(options || []).forEach(opt => {
  220 + const ov = opt && opt.value != null ? String(opt.value) : ''
  221 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  222 + })
  223 + return labels.filter(Boolean).join(',') || '-'
  224 + },
  225 + async loadDetail() {
  226 + this.loading = true
  227 + try {
  228 + const data = await this.mockGetDetail(this.id)
  229 + this.form = data || {}
  230 + } catch (e) {
  231 + this.form = {}
  232 + uni.showToast({ title: '详情加载失败', icon: 'none' })
  233 + } finally {
  234 + this.loading = false
  235 + }
  236 + },
  237 + mockGetDetail(id) {
  238 + return new Promise(resolve => {
  239 + const stored = this.tryLoadFromStorage(id)
  240 + if (stored) return setTimeout(() => resolve(stored), 180)
  241 + setTimeout(() => resolve(this.buildMockDetail(id)), 180)
  242 + })
  243 + },
  244 + tryLoadFromStorage(id) {
  245 + try {
  246 + const raw = uni.getStorageSync('DOMESTIC_TRADE_RECORDS')
  247 + const arr = Array.isArray(raw) ? raw : (raw && Array.isArray(raw.list) ? raw.list : [])
  248 + if (!id) return arr && arr[0] ? arr[0] : null
  249 + const found = (arr || []).find(it => it && String(it.id || '') === String(id))
  250 + return found || null
  251 + } catch (e) {
  252 + return null
  253 + }
  254 + },
  255 + buildMockDetail(id) {
  256 + const now = new Date()
  257 + const createDate = this.formatDate(now)
  258 + return {
  259 + id: id || '1',
  260 + companyName: '华东商贸有限公司1',
  261 + companyNature: 'RECYCLE,OTHER',
  262 + companyNatureOther: '再生资源综合回收',
  263 + bankName: '中国工商银行上海分行',
  264 + bankAccount: '6222020202020202',
  265 + registeredCapital: '500',
  266 + annualTurnover: '2600',
  267 + legalRepresentative: '张三',
  268 + companyFoundedDate: '2018-06-01',
  269 + address: '上海市浦东新区示例路 88 号',
  270 + businessOwner: '李四',
  271 + position: '总经理',
  272 + phone: '13800000000',
  273 + fax: '021-88888888',
  274 + legalBusinessRelation: '亲属',
  275 + liquidWorkingCapital: '流动资金 300 万;购销结算期限 30 天;债权债务情况正常',
  276 + fixedAssets: '厂房产权自有 2000㎡;主要设备投资 800 万;仓库自有 1200㎡;正常库存量 300 吨',
  277 + purchaseSituation: '主要品种:铜、铁;收购量:月均 1200 吨;上年度利润:铜 120 万,铁 80 万;入库流程规范',
  278 + purchaseSource: 'OTHER',
  279 + purchaseSourceOther: '本地回收站合作渠道',
  280 + productionSituation: '产品:再生铜;产能:月均 800 吨;能耗:电 40 万度/月',
  281 + salesSituation: '渠道:长期客户+现货;回款方式:承兑/转账;结算期限:30-60 天',
  282 + preferentialPolicy: 'NO',
  283 + preferentialPolicyDetail: '',
  284 + punishmentRecord: 'NO',
  285 + scopeMatch: '相符',
  286 + futuresInvest: 'YES',
  287 + investNature: 'HEDGE_MAIN',
  288 + lastYearFuturesProfitLoss: '盈利 15 万',
  289 + cooperationStartYear: '2021',
  290 + mainOperationMode: '现货+月度计划',
  291 + badRecordPlanFail: 'NO',
  292 + planNotFulfilled: 'NO',
  293 + operationNorms: '账务按月对账;开票品名一致;出库流程规范;运输发票齐全',
  294 + commonMaterialIssues: '含杂偏高、含水偏高',
  295 + otherCooperationIssues: '暂无',
  296 + createDate,
  297 + reviewDate: '',
  298 + attachments: [
  299 + { id: 'mock-file-1', name: '资信调查表.pdf' },
  300 + { id: 'mock-file-2', name: '营业执照.jpg' }
  301 + ]
  302 + }
  303 + },
  304 + formatDate(d) {
  305 + const y = d.getFullYear()
  306 + const m = String(d.getMonth() + 1).padStart(2, '0')
  307 + const da = String(d.getDate()).padStart(2, '0')
  308 + return `${y}-${m}-${da}`
  309 + },
  310 + onDownload(item) {
  311 + if (!item || !item.id) return
  312 + downloadFile(item.id, item.name || 'download')
  313 + }
  314 + }
  315 +}
  316 +</script>
  317 +
  318 +<style lang="scss" scoped>
  319 +.page {
  320 + display: flex;
  321 + flex-direction: column;
  322 + height: 100%;
  323 +}
  324 +
  325 +.scroll {
  326 + flex: 1;
  327 + padding: 8rpx 0 24rpx 0;
  328 +}
  329 +
  330 +.detail-page {
  331 + background: #f3f3f3;
  332 +}
  333 +
  334 +.title-header {
  335 + display: flex;
  336 + align-items: center;
  337 + padding: 24rpx 32rpx 12rpx;
  338 +
  339 + .title-header_icon {
  340 + width: 36rpx;
  341 + height: 36rpx;
  342 + margin-right: 12rpx;
  343 + }
  344 +
  345 + span {
  346 + font-size: 34rpx;
  347 + font-weight: 600;
  348 + color: rgba(0, 0, 0, 0.9);
  349 + }
  350 +}
  351 +
  352 +.section {
  353 + padding: 32rpx;
  354 + background: #fff;
  355 + margin-bottom: 20rpx;
  356 +}
  357 +
  358 +.row {
  359 + display: flex;
  360 + margin-bottom: 28rpx;
  361 +
  362 + &:last-child {
  363 + margin-bottom: 0;
  364 + }
  365 +
  366 + &.company {
  367 + font-size: 36rpx;
  368 + font-weight: 600;
  369 + color: rgba(0, 0, 0, 0.9);
  370 + padding-top: 8rpx;
  371 + line-height: 50rpx;
  372 + }
  373 +
  374 + .label {
  375 + max-width: 420rpx;
  376 + margin-right: 20rpx;
  377 + line-height: 32rpx;
  378 + font-size: 28rpx;
  379 + color: rgba(0, 0, 0, 0.6);
  380 + }
  381 +
  382 + .value {
  383 + flex: 1;
  384 + line-height: 32rpx;
  385 + font-size: 28rpx;
  386 + color: rgba(0, 0, 0, 0.9);
  387 + text-align: right;
  388 + word-break: break-all;
  389 +
  390 + &.act {
  391 + color: $theme-primary;
  392 + }
  393 +
  394 + &.pre {
  395 + white-space: pre-wrap;
  396 + }
  397 + }
  398 +}
  399 +.title-header {
  400 + background-color: #ffffff;
  401 +}
  402 +.file-item {
  403 + margin-bottom: 12rpx;
  404 +
  405 + &:last-child {
  406 + margin-bottom: 0;
  407 + }
  408 +}
  409 +</style>
... ...
  1 +<template>
  2 + <view class="page">
  3 + <view class="dev-list-fixed">
  4 + <view class="search-row">
  5 + <uni-search-bar v-model="searchKeyword" radius="6" placeholder="请输入单位名称" clearButton="auto"
  6 + cancelButton="none" bgColor="#F3F3F3" textColor="rgba(0,0,0,0.4)" @confirm="search"
  7 + @input="onSearchInput" />
  8 + <view class="tool-icons">
  9 + <image class="tool-icon" src="/static/images/dev_manage/add_icon.png" @click="onAdd" />
  10 + <image class="tool-icon" src="/static/images/dev_manage/filter_icon.png" @click="openFilter" />
  11 + </view>
  12 + </view>
  13 + </view>
  14 +
  15 + <view class="list-box">
  16 + <card-list ref="cardRef" :fetch-fn="fetchList" :query="query" :extra="extraParams" row-key="id"
  17 + :enable-refresh="true" :enable-load-more="true" @loaded="onCardLoaded" @error="onCardError">
  18 + <template v-slot="{ item }">
  19 + <view class="card" @click.stop="onCardClick(item)">
  20 + <view class="card-header">
  21 + <text class="title omit2">{{ item.companyName || '-' }}</text>
  22 + <text :class="['status', `status_${item.auditStatus}`]">{{ getAuditStatusText(item.auditStatus) }}</text>
  23 + </view>
  24 + <view class="info-row">
  25 + <text>公司性质</text><text>{{ item.companyNature || '-' }}</text>
  26 + </view>
  27 + <view class="info-row">
  28 + <text>电话</text><text>{{ item.phone || '-' }}</text>
  29 + </view>
  30 + <view class="info-row">
  31 + <text>业务负责人</text><text>{{ item.businessOwner || '-' }}</text>
  32 + </view>
  33 + <view class="info-row">
  34 + <text>创建日期</text><text>{{ item.createDate || '-' }}</text>
  35 + </view>
  36 + </view>
  37 + </template>
  38 + </card-list>
  39 + </view>
  40 +
  41 + <filter-modal :visible.sync="filterVisible" :value.sync="filterForm" title="筛选" @reset="onFilterReset"
  42 + @confirm="onFilterConfirm">
  43 + <template v-slot="{ model }">
  44 + <view class="filter-form">
  45 + <view class="form-item">
  46 + <view class="label">审核状态</view>
  47 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  48 + v-model="model.auditStatus" @change="onAuditStatusChange" :localdata="auditStatusOptions" />
  49 + </view>
  50 + <view class="form-item">
  51 + <view class="label">登记日期</view>
  52 + <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
  53 + </view>
  54 + </view>
  55 + </template>
  56 + </filter-modal>
  57 + </view>
  58 +</template>
  59 +
  60 +<script>
  61 +import CardList from '@/components/card/index.vue'
  62 +import FilterModal from '@/components/filter/index.vue'
  63 +
  64 +export default {
  65 + name: 'DomesticTradeList',
  66 + components: { CardList, FilterModal },
  67 + data() {
  68 + return {
  69 + searchKeyword: '',
  70 + searchKeywordDebounced: '',
  71 + searchDebounceTimer: null,
  72 + query: {
  73 + companyName: '',
  74 + auditStatus: '',
  75 + dateRange: []
  76 + },
  77 + extraParams: {},
  78 + currentItems: [],
  79 + filterVisible: false,
  80 + filterForm: {
  81 + auditStatus: '',
  82 + dateRange: []
  83 + },
  84 + auditStatusOptions: [
  85 + { value: '', text: '全部' },
  86 + { value: 'AUDIT', text: '审核中' },
  87 + { value: 'PASS', text: '通过' },
  88 + { value: 'REFUSE', text: '驳回' },
  89 + { value: 'CANCEL', text: '已取消' }
  90 + ],
  91 + mockAll: []
  92 + }
  93 + },
  94 + watch: {
  95 + searchKeywordDebounced(v) {
  96 + this.query = { ...this.query, companyName: v || '' }
  97 + }
  98 + },
  99 + created() {
  100 + this.mockAll = this.buildMockList(60)
  101 + },
  102 + onReachBottom() {
  103 + if (this.$refs && this.$refs.cardRef && this.$refs.cardRef.onLoadMore) {
  104 + this.$refs.cardRef.onLoadMore()
  105 + }
  106 + },
  107 + beforeDestroy() {
  108 + if (this.searchDebounceTimer) {
  109 + clearTimeout(this.searchDebounceTimer)
  110 + this.searchDebounceTimer = null
  111 + }
  112 + },
  113 + methods: {
  114 + onAdd() {
  115 + uni.navigateTo({ url: '/pages/domestic_trade/add' })
  116 + },
  117 + onCardLoaded({ items }) {
  118 + this.currentItems = items
  119 + },
  120 + onCardError() {
  121 + uni.showToast({ title: '列表加载失败', icon: 'none' })
  122 + },
  123 + onSearchInput() {
  124 + if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer)
  125 + this.searchDebounceTimer = setTimeout(() => {
  126 + this.searchKeywordDebounced = this.searchKeyword
  127 + this.searchDebounceTimer = null
  128 + }, 1200)
  129 + },
  130 + search(e) {
  131 + const val = e && e.value != null ? e.value : this.searchKeyword
  132 + this.searchKeyword = val
  133 + this.searchKeywordDebounced = val
  134 + },
  135 + openFilter() {
  136 + this.filterForm = {
  137 + auditStatus: this.query.auditStatus || '',
  138 + dateRange: Array.isArray(this.query.dateRange) ? this.query.dateRange.slice(0) : []
  139 + }
  140 + this.filterVisible = true
  141 + },
  142 + onFilterReset(payload) {
  143 + this.filterForm = payload
  144 + },
  145 + onFilterConfirm(payload) {
  146 + this.query = {
  147 + companyName: this.query.companyName || '',
  148 + auditStatus: payload.auditStatus || '',
  149 + dateRange: Array.isArray(payload.dateRange) ? payload.dateRange : []
  150 + }
  151 + },
  152 + onAuditStatusChange(e) {
  153 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  154 + this.filterForm.auditStatus = raw
  155 + },
  156 + getAuditStatusText(status) {
  157 + const found = (this.auditStatusOptions || []).find(it => it.value === status)
  158 + return found ? found.text : (status || '-')
  159 + },
  160 + fetchList({ pageIndex, pageSize, query }) {
  161 + const listAll = Array.isArray(this.mockAll) ? this.mockAll : []
  162 + const q = query || {}
  163 + const name = (q.companyName || '').trim()
  164 + const status = q.auditStatus || ''
  165 + const range = Array.isArray(q.dateRange) ? q.dateRange : []
  166 + const start = range && range.length === 2 ? range[0] : ''
  167 + const end = range && range.length === 2 ? range[1] : ''
  168 +
  169 + let filtered = listAll.slice(0)
  170 + if (name) {
  171 + const kw = name.toLowerCase()
  172 + filtered = filtered.filter(it => String(it.companyName || '').toLowerCase().includes(kw))
  173 + }
  174 + if (status) {
  175 + filtered = filtered.filter(it => it.auditStatus === status)
  176 + }
  177 + if (start && end) {
  178 + const s = String(start)
  179 + const ed = String(end)
  180 + filtered = filtered.filter(it => {
  181 + const d = String(it.registerDate || it.createDate || '')
  182 + return d >= s && d <= ed
  183 + })
  184 + }
  185 +
  186 + const totalCount = filtered.length
  187 + const begin = (Number(pageIndex || 1) - 1) * Number(pageSize || 10)
  188 + const endIdx = begin + Number(pageSize || 10)
  189 + const records = filtered.slice(begin, endIdx)
  190 + const hasNext = endIdx < totalCount
  191 +
  192 + return new Promise(resolve => {
  193 + setTimeout(() => resolve({ records, totalCount, hasNext }), 220)
  194 + })
  195 + },
  196 + onCardClick(item) {
  197 + uni.navigateTo({ url: '/pages/domestic_trade/detail?id=' + item.id })
  198 + },
  199 + buildMockList(count) {
  200 + const n = Number(count || 0)
  201 + const natures = ['民营', '国企', '外资', '合资', '其他']
  202 + const statusPool = ['AUDIT', 'PASS', 'REFUSE', 'CANCEL']
  203 + const baseNames = ['华东', '华南', '华北', '西南', '中原', '海纳', '启航', '远成', '融盛', '天泽']
  204 + const owners = ['张三', '李四', '王五', '赵六', '周七', '吴八', '郑九', '钱十']
  205 + const list = []
  206 + for (let i = 0; i < n; i++) {
  207 + const idx = i + 1
  208 + const companyName = `${baseNames[i % baseNames.length]}商贸有限公司${idx}`
  209 + const auditStatus = statusPool[i % statusPool.length]
  210 + const companyNature = natures[i % natures.length]
  211 + const businessOwner = owners[i % owners.length]
  212 + const phone = this.mockPhone(i)
  213 + const daysAgo = i % 40
  214 + const date = this.formatDate(this.addDays(new Date(), -daysAgo))
  215 + list.push({
  216 + id: String(idx),
  217 + companyName,
  218 + companyNature,
  219 + phone,
  220 + businessOwner,
  221 + auditStatus,
  222 + registerDate: date,
  223 + createDate: date
  224 + })
  225 + }
  226 + return list
  227 + },
  228 + mockPhone(i) {
  229 + const s = String(13000000000 + (i % 900000000))
  230 + return s.slice(0, 11)
  231 + },
  232 + addDays(d, days) {
  233 + const dt = new Date(d.getTime())
  234 + dt.setDate(dt.getDate() + Number(days || 0))
  235 + return dt
  236 + },
  237 + formatDate(d) {
  238 + const y = d.getFullYear()
  239 + const m = String(d.getMonth() + 1).padStart(2, '0')
  240 + const da = String(d.getDate()).padStart(2, '0')
  241 + return `${y}-${m}-${da}`
  242 + }
  243 + }
  244 +}
  245 +</script>
  246 +
  247 +<style lang="scss" scoped>
  248 +.page {
  249 + display: flex;
  250 + flex-direction: column;
  251 + height: 100vh;
  252 +}
  253 +
  254 +.dev-list-fixed {
  255 + position: fixed;
  256 + top: 96rpx;
  257 + left: 0;
  258 + right: 0;
  259 + z-index: 2;
  260 + background: #fff;
  261 +
  262 + .search-row {
  263 + display: flex;
  264 + align-items: center;
  265 + padding: 16rpx 32rpx;
  266 +
  267 + .uni-searchbar {
  268 + padding: 0;
  269 + flex: 1;
  270 + }
  271 +
  272 + .tool-icons {
  273 + display: flex;
  274 +
  275 + .tool-icon {
  276 + width: 48rpx;
  277 + height: 48rpx;
  278 + display: block;
  279 + margin-left: 32rpx;
  280 + }
  281 + }
  282 + }
  283 +}
  284 +
  285 +::v-deep .uni-searchbar__box {
  286 + height: 80rpx !important;
  287 + justify-content: start;
  288 +
  289 + .uni-searchbar__box-search-input {
  290 + font-size: 32rpx !important;
  291 + }
  292 +}
  293 +
  294 +.list-box {
  295 + flex: 1;
  296 + padding-top: 140rpx;
  297 +
  298 + .card {
  299 + position: relative;
  300 + }
  301 +
  302 + .card-header {
  303 + margin-bottom: 28rpx;
  304 + position: relative;
  305 +
  306 + .title {
  307 + font-size: 36rpx;
  308 + font-weight: 600;
  309 + line-height: 50rpx;
  310 + color: rgba(0, 0, 0, 0.9);
  311 + width: 578rpx;
  312 + }
  313 +
  314 + .status {
  315 + position: absolute;
  316 + top: -32rpx;
  317 + right: -12rpx;
  318 + height: 48rpx;
  319 + line-height: 48rpx;
  320 + font-weight: 600;
  321 + color: #fff;
  322 + font-size: 24rpx;
  323 + padding: 0 14rpx;
  324 + border-radius: 6rpx;
  325 +
  326 + &.status_AUDIT {
  327 + background: $theme-primary;
  328 + }
  329 +
  330 + &.status_PASS {
  331 + background: #2BA471;
  332 + }
  333 +
  334 + &.status_REFUSE {
  335 + background: #D54941;
  336 + }
  337 +
  338 + &.status_CANCEL {
  339 + background: #E7E7E7;
  340 + color: rgba(0, 0, 0, 0.9);
  341 + }
  342 + }
  343 + }
  344 +
  345 + .info-row {
  346 + display: flex;
  347 + align-items: center;
  348 + color: rgba(0, 0, 0, 0.6);
  349 + font-size: 28rpx;
  350 + margin-bottom: 24rpx;
  351 + height: 32rpx;
  352 +
  353 + &:last-child {
  354 + margin-bottom: 0;
  355 + }
  356 +
  357 + text {
  358 + width: 50%;
  359 +
  360 + &:last-child {
  361 + color: rgba(0, 0, 0, 0.9);
  362 + width: 50%;
  363 + }
  364 + }
  365 + }
  366 +}
  367 +
  368 +.filter-form {
  369 + .form-item {
  370 + margin-bottom: 24rpx;
  371 + }
  372 +
  373 + .label {
  374 + margin-bottom: 20rpx;
  375 + color: rgba(0, 0, 0, 0.9);
  376 + height: 44rpx;
  377 + line-height: 44rpx;
  378 + font-size: 30rpx;
  379 + }
  380 +}
  381 +</style>
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <view class="title-header">
  6 + <image class="title-header_icon" src="/static/images/title.png" />
  7 + <span>基本资料</span>
  8 + </view>
  9 +
  10 + <uni-list-item title="单位名称">
  11 + <template v-slot:footer>
  12 + <uni-easyinput v-model="form.companyName" placeholder="请输入单位名称" :inputBorder="false" />
  13 + </template>
  14 + </uni-list-item>
  15 +
  16 + <uni-list-item class="select-item" :class="form.companyNatureName ? 'is-filled' : 'is-empty'" clickable
  17 + @click="openMultiSheet('companyNature')" :rightText="displayLabel('companyNatureName')" showArrow>
  18 + <template v-slot:body>
  19 + <view class="item-title"><text>公司性质</text></view>
  20 + </template>
  21 + </uni-list-item>
  22 + <uni-list-item v-if="showCompanyNatureOther" class="mgb10" title="其他">
  23 + <template v-slot:footer>
  24 + <uni-easyinput v-model="form.companyNatureOther" placeholder="请输入其他公司性质" :inputBorder="false" />
  25 + </template>
  26 + </uni-list-item>
  27 +
  28 + <uni-list-item title="开户行">
  29 + <template v-slot:footer>
  30 + <uni-easyinput v-model="form.bankName" placeholder="请输入开户行" :inputBorder="false" />
  31 + </template>
  32 + </uni-list-item>
  33 +
  34 + <uni-list-item title="账号">
  35 + <template v-slot:footer>
  36 + <uni-easyinput v-model="form.bankAccount" placeholder="请输入账号" :inputBorder="false" />
  37 + </template>
  38 + </uni-list-item>
  39 +
  40 + <uni-list-item class="amount-item">
  41 + <template v-slot:body>
  42 + <view class="item-title"><text>注册资金</text></view>
  43 + </template>
  44 + <template v-slot:footer>
  45 + <view class="amount-row">
  46 + <uni-easyinput type="digit" v-model="form.registeredCapital" placeholder="请输入" :inputBorder="false" />
  47 + <text class="unit">万元</text>
  48 + </view>
  49 + </template>
  50 + </uni-list-item>
  51 +
  52 + <uni-list-item class="amount-item">
  53 + <template v-slot:body>
  54 + <view class="item-title"><text>年营业额</text></view>
  55 + </template>
  56 + <template v-slot:footer>
  57 + <view class="amount-row">
  58 + <uni-easyinput type="digit" v-model="form.annualTurnover" placeholder="请输入" :inputBorder="false" />
  59 + <text class="unit">万元</text>
  60 + </view>
  61 + </template>
  62 + </uni-list-item>
  63 +
  64 + <uni-list-item title="法人代表">
  65 + <template v-slot:footer>
  66 + <uni-easyinput v-model="form.legalRepresentative" placeholder="请输入法人代表" :inputBorder="false" />
  67 + </template>
  68 + </uni-list-item>
  69 +
  70 + <uni-list-item title="公司成立时间">
  71 + <template v-slot:footer>
  72 + <uni-datetime-picker type="date" v-model="form.companyFoundedDate" />
  73 + </template>
  74 + </uni-list-item>
  75 +
  76 + <uni-list-item title="地址">
  77 + <template v-slot:footer>
  78 + <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
  79 + </template>
  80 + </uni-list-item>
  81 +
  82 + <uni-list-item title="业务负责人">
  83 + <template v-slot:footer>
  84 + <uni-easyinput v-model="form.businessOwner" placeholder="请输入业务负责人" :inputBorder="false" />
  85 + </template>
  86 + </uni-list-item>
  87 +
  88 + <uni-list-item title="职务">
  89 + <template v-slot:footer>
  90 + <uni-easyinput v-model="form.position" placeholder="请输入职务" :inputBorder="false" />
  91 + </template>
  92 + </uni-list-item>
  93 +
  94 + <uni-list-item title="电话">
  95 + <template v-slot:footer>
  96 + <uni-easyinput type="number" v-model="form.phone" placeholder="请输入手机号码" :inputBorder="false" />
  97 + </template>
  98 + </uni-list-item>
  99 +
  100 + <uni-list-item title="传真">
  101 + <template v-slot:footer>
  102 + <uni-easyinput v-model="form.fax" placeholder="请输入传真" :inputBorder="false" />
  103 + </template>
  104 + </uni-list-item>
  105 +
  106 + <uni-list-item class="mgb10" title="法人与业务负责人关系">
  107 + <template v-slot:footer>
  108 + <uni-easyinput v-model="form.legalBusinessRelation" placeholder="请输入" :inputBorder="false" />
  109 + </template>
  110 + </uni-list-item>
  111 +
  112 + <view class="title-header">
  113 + <image class="title-header_icon" src="/static/images/title.png" />
  114 + <span>资产状况</span>
  115 + </view>
  116 +
  117 + <uni-list-item title="流动资金">
  118 + <template v-slot:footer>
  119 + <uni-easyinput type="textarea" v-model="form.liquidWorkingCapital" placeholder="1、流动资金 2、购、销结算期限 3、债券债务情况"
  120 + :inputBorder="false" maxlength="2000" />
  121 + </template>
  122 + </uni-list-item>
  123 +
  124 + <uni-list-item class="mgb10" title="固定资产">
  125 + <template v-slot:footer>
  126 + <uni-easyinput type="textarea" v-model="form.fixedAssets" placeholder="1、厂房/办公楼产权、面积 2、主要设备投资规模及产权 3、仓库或货场产权、面积 4、正常库存量"
  127 + :inputBorder="false" maxlength="3000" />
  128 + </template>
  129 + </uni-list-item>
  130 +
  131 + <view class="title-header">
  132 + <image class="title-header_icon" src="/static/images/title.png" />
  133 + <span>生产经营环节风险调查</span>
  134 + </view>
  135 +
  136 + <uni-list-item title="收购情况">
  137 + <template v-slot:footer>
  138 + <uni-easyinput type="textarea" v-model="form.purchaseSituation"
  139 + placeholder="1、主要品种及收购量 2、经营绩效状况(上年度利润,区分铜/铁等) 4、入库流程及入库品名" :inputBorder="false"
  140 + maxlength="3000" />
  141 + </template>
  142 + </uni-list-item>
  143 + <uni-list-item class="select-item" :class="form.purchaseSourceName ? 'is-filled' : 'is-empty'" clickable
  144 + @click="openSheet('purchaseSource')" :rightText="displayLabel('purchaseSourceName')" showArrow>
  145 + <template v-slot:body>
  146 + <view class="item-title"><text>货源来源</text></view>
  147 + </template>
  148 + </uni-list-item>
  149 + <uni-list-item v-if="showPurchaseSourceOther" class="mgb10" title="其他">
  150 + <template v-slot:footer>
  151 + <uni-easyinput v-model="form.purchaseSourceOther" placeholder="请输入其他货源来源" :inputBorder="false" />
  152 + </template>
  153 + </uni-list-item>
  154 +
  155 + <uni-list-item title="生产情况">
  156 + <template v-slot:footer>
  157 + <uni-easyinput type="textarea" v-model="form.productionSituation" placeholder="1、产品介绍 2、产能及对应能耗"
  158 + :inputBorder="false" maxlength="2000" />
  159 + </template>
  160 + </uni-list-item>
  161 +
  162 + <uni-list-item title="销售情况">
  163 + <template v-slot:footer>
  164 + <uni-easyinput type="textarea" v-model="form.salesSituation" placeholder="销售渠道、销量及操作方式、货款回笼方式、结算期限"
  165 + :inputBorder="false" maxlength="2000" />
  166 + </template>
  167 + </uni-list-item>
  168 +
  169 + <uni-list-item class="select-item" :class="form.preferentialPolicyName ? 'is-filled' : 'is-empty'" clickable
  170 + @click="openSheet('preferentialPolicy')" :rightText="displayLabel('preferentialPolicyName')" showArrow>
  171 + <template v-slot:body>
  172 + <view class="item-title"><text>是否享受优惠政策</text></view>
  173 + </template>
  174 + </uni-list-item>
  175 + <uni-list-item class="mgb10" title="详细说明">
  176 + <template v-slot:footer>
  177 + <uni-easyinput type="textarea" v-model="form.preferentialPolicyDetail" placeholder="请输入详细说明"
  178 + :inputBorder="false" maxlength="2000" />
  179 + </template>
  180 + </uni-list-item>
  181 +
  182 + <uni-list-item class="select-item" :class="form.punishmentRecordName ? 'is-filled' : 'is-empty'" clickable
  183 + @click="openSheet('punishmentRecord')" :rightText="displayLabel('punishmentRecordName')" showArrow>
  184 + <template v-slot:body>
  185 + <view class="item-title"><text>是否有被处罚记录</text></view>
  186 + </template>
  187 + </uni-list-item>
  188 + <uni-list-item class="mgb10" title="实际经营范围与法定经营范围是否相符">
  189 + <template v-slot:footer>
  190 + <uni-easyinput type="textarea" v-model="form.scopeMatch" placeholder="请输入" :inputBorder="false"
  191 + maxlength="2000" />
  192 + </template>
  193 + </uni-list-item>
  194 +
  195 + <uni-list-item class="select-item" :class="form.futuresInvestName ? 'is-filled' : 'is-empty'" clickable
  196 + @click="openSheet('futuresInvest')" :rightText="displayLabel('futuresInvestName')" showArrow>
  197 + <template v-slot:body>
  198 + <view class="item-title"><text>是否投资期货</text></view>
  199 + </template>
  200 + </uni-list-item>
  201 +
  202 + <uni-list-item class="select-item" :class="form.investNatureName ? 'is-filled' : 'is-empty'" clickable
  203 + @click="openSheet('investNature')" :rightText="displayLabel('investNatureName')" showArrow>
  204 + <template v-slot:body>
  205 + <view class="item-title"><text>投资性质</text></view>
  206 + </template>
  207 + </uni-list-item>
  208 +
  209 + <uni-list-item class="mgb10" title="上年度期货盈亏">
  210 + <template v-slot:footer>
  211 + <uni-easyinput v-model="form.lastYearFuturesProfitLoss" placeholder="请输入" :inputBorder="false" />
  212 + </template>
  213 + </uni-list-item>
  214 +
  215 + <view class="title-header">
  216 + <image class="title-header_icon" src="/static/images/title.png" />
  217 + <span>与我司的合作状况</span>
  218 + </view>
  219 +
  220 + <uni-list-item class="amount-item">
  221 + <template v-slot:body>
  222 + <view class="item-title"><text>合作年限</text></view>
  223 + </template>
  224 + <template v-slot:footer>
  225 + <view class="amount-row">
  226 + <text class="prefix">从</text>
  227 + <uni-easyinput type="digit" v-model="form.cooperationStartYear" placeholder="年份" :inputBorder="false" />
  228 + <text class="suffix">年开始合作</text>
  229 + </view>
  230 + </template>
  231 + </uni-list-item>
  232 +
  233 + <uni-list-item title="主要操作方式">
  234 + <template v-slot:footer>
  235 + <uni-easyinput type="textarea" v-model="form.mainOperationMode" placeholder="请输入"
  236 + :inputBorder="false" maxlength="2000" />
  237 + </template>
  238 + </uni-list-item>
  239 +
  240 + <uni-list-item class="select-item" :class="form.badRecordPlanFailName ? 'is-filled' : 'is-empty'" clickable
  241 + @click="openSheet('badRecordPlanFail')" :rightText="displayLabel('badRecordPlanFailName')" showArrow>
  242 + <template v-slot:body>
  243 + <view class="item-title"><text>是否有计划落空的不良记录</text></view>
  244 + </template>
  245 + </uni-list-item>
  246 + <uni-list-item class="select-item" :class="form.planNotFulfilledName ? 'is-filled' : 'is-empty'" clickable
  247 + @click="openSheet('planNotFulfilled')" :rightText="displayLabel('planNotFulfilledName')" showArrow>
  248 + <template v-slot:body>
  249 + <view class="item-title"><text>是否有计划履行不到位现象(时间、数量等)</text></view>
  250 + </template>
  251 + </uni-list-item>
  252 +
  253 + <uni-list-item title="操作规范性">
  254 + <template v-slot:footer>
  255 + <uni-easyinput type="textarea" v-model="form.operationNorms" placeholder="1、进销账务如何处理 2、开票品名与出库单品名是否一致 3、出库流程是否规范 4、运输发票情况"
  256 + :inputBorder="false" maxlength="3000" />
  257 + </template>
  258 + </uni-list-item>
  259 +
  260 + <uni-list-item title="常见料质问题">
  261 + <template v-slot:footer>
  262 + <uni-easyinput type="textarea" v-model="form.commonMaterialIssues" placeholder="请输入"
  263 + :inputBorder="false" maxlength="2000" />
  264 + </template>
  265 + </uni-list-item>
  266 +
  267 + <uni-list-item class="mgb10" title="合作中的其他问题">
  268 + <template v-slot:footer>
  269 + <uni-easyinput type="textarea" v-model="form.otherCooperationIssues" placeholder="请输入"
  270 + :inputBorder="false" maxlength="2000" />
  271 + </template>
  272 + </uni-list-item>
  273 +
  274 + <view class="title-header">
  275 + <image class="title-header_icon" src="/static/images/title.png" />
  276 + <span>其他</span>
  277 + </view>
  278 +
  279 + <uni-list-item title="创建日期">
  280 + <template v-slot:footer>
  281 + <uni-datetime-picker type="date" v-model="form.createDate" />
  282 + </template>
  283 + </uni-list-item>
  284 +
  285 + <uni-list-item title="评审时间">
  286 + <template v-slot:footer>
  287 + <uni-datetime-picker type="date" v-model="form.reviewDate" />
  288 + </template>
  289 + </uni-list-item>
  290 +
  291 + <uni-list-item class="mgb10" title="附件">
  292 + <template v-slot:footer>
  293 + <view class="attach-box">
  294 + <view v-for="(f, idx) in form.attachments" :key="idx" class="attach-row">
  295 + <FileUpload :value="f" @input="onAttachmentInput(idx, $event)" />
  296 + <text class="attach-del" @click.stop="removeAttachment(idx)">删除</text>
  297 + </view>
  298 + <view class="attach-row">
  299 + <FileUpload :value="newAttachment" @input="onAddAttachment" />
  300 + </view>
  301 + </view>
  302 + </template>
  303 + </uni-list-item>
  304 + </uni-list>
  305 + </scroll-view>
  306 +
  307 + <view class="footer">
  308 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '保存中...' : '保存' }}</button>
  309 + </view>
  310 +
  311 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  312 + @confirm="onSheetConfirm" />
  313 + <MultiSelectSheet :visible.sync="multiSheet.visible" :title="multiSheet.title" :options="multiSheet.options"
  314 + v-model="multiSheet.value" @confirm="onMultiSheetConfirm" />
  315 + </view>
  316 +</template>
  317 +
  318 +<script>
  319 +import FileUpload from '@/components/file-upload/index.vue'
  320 +import SingleSelectSheet from '@/components/single-select/index.vue'
  321 +import MultiSelectSheet from '@/components/multi-select/index.vue'
  322 +
  323 +export default {
  324 + name: 'DomesticTradeModify',
  325 + components: { FileUpload, SingleSelectSheet, MultiSelectSheet },
  326 + data() {
  327 + return {
  328 + id: '',
  329 + submitting: false,
  330 + loading: false,
  331 + newAttachment: { id: '', name: '' },
  332 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  333 + multiSheet: { visible: false, title: '', options: [], field: '', value: '' },
  334 + yesNoOptions: [
  335 + { label: '是', value: 'YES' },
  336 + { label: '否', value: 'NO' }
  337 + ],
  338 + investNatureOptions: [
  339 + { label: '投机', value: 'SPECULATION' },
  340 + { label: '保值', value: 'HEDGE' },
  341 + { label: '保值为主投机为辅', value: 'HEDGE_MAIN' }
  342 + ],
  343 + companyNatureOptions: [
  344 + { label: '回收公司', value: 'RECYCLE' },
  345 + { label: '贸易公司', value: 'TRADE' },
  346 + { label: '进口拆解', value: 'IMPORT_DISMANTLE' },
  347 + { label: '工业制造', value: 'INDUSTRY_MANUFACTURE' },
  348 + { label: '福利企业', value: 'WELFARE_ENTERPRISE' },
  349 + { label: '其他', value: 'OTHER' }
  350 + ],
  351 + purchaseSourceOptions: [
  352 + { label: '国外进口', value: 'IMPORT' },
  353 + { label: '本企业报废', value: 'SELF_SCRAP' },
  354 + { label: '零散收购', value: 'SCATTERED' },
  355 + { label: '其他', value: 'OTHER' }
  356 + ],
  357 + form: {
  358 + id: '',
  359 + companyName: '',
  360 + companyNature: '',
  361 + companyNatureName: '',
  362 + companyNatureOther: '',
  363 + bankName: '',
  364 + bankAccount: '',
  365 + registeredCapital: '',
  366 + annualTurnover: '',
  367 + legalRepresentative: '',
  368 + companyFoundedDate: '',
  369 + address: '',
  370 + businessOwner: '',
  371 + position: '',
  372 + phone: '',
  373 + fax: '',
  374 + legalBusinessRelation: '',
  375 + liquidWorkingCapital: '',
  376 + fixedAssets: '',
  377 + purchaseSituation: '',
  378 + purchaseSource: '',
  379 + purchaseSourceName: '',
  380 + purchaseSourceOther: '',
  381 + productionSituation: '',
  382 + salesSituation: '',
  383 + preferentialPolicy: '',
  384 + preferentialPolicyName: '',
  385 + preferentialPolicyDetail: '',
  386 + punishmentRecord: '',
  387 + punishmentRecordName: '',
  388 + scopeMatch: '',
  389 + futuresInvest: '',
  390 + futuresInvestName: '',
  391 + investNature: '',
  392 + investNatureName: '',
  393 + lastYearFuturesProfitLoss: '',
  394 + cooperationStartYear: '',
  395 + mainOperationMode: '',
  396 + badRecordPlanFail: '',
  397 + badRecordPlanFailName: '',
  398 + planNotFulfilled: '',
  399 + planNotFulfilledName: '',
  400 + operationNorms: '',
  401 + commonMaterialIssues: '',
  402 + otherCooperationIssues: '',
  403 + createDate: '',
  404 + reviewDate: '',
  405 + attachments: []
  406 + }
  407 + }
  408 + },
  409 + computed: {
  410 + showCompanyNatureOther() {
  411 + const v = String(this.form.companyNature || '')
  412 + return v.split(',').includes('OTHER')
  413 + },
  414 + showPurchaseSourceOther() {
  415 + return this.form.purchaseSource === 'OTHER'
  416 + }
  417 + },
  418 + onLoad(query) {
  419 + const id = (query && (query.id || query.code)) ? String(query.id || query.code) : ''
  420 + this.id = id
  421 + this.loadDetail()
  422 + },
  423 + methods: {
  424 + displayLabel(field) {
  425 + const m = this.form
  426 + const map = {
  427 + companyNatureName: '请选择公司性质',
  428 + purchaseSourceName: '请选择货源来源',
  429 + preferentialPolicyName: '请选择',
  430 + punishmentRecordName: '请选择',
  431 + futuresInvestName: '请选择',
  432 + investNatureName: '请选择',
  433 + badRecordPlanFailName: '请选择',
  434 + planNotFulfilledName: '请选择'
  435 + }
  436 + const val = m[field]
  437 + return val ? String(val) : map[field]
  438 + },
  439 + openSheet(field) {
  440 + const map = {
  441 + purchaseSource: { title: '货源来源', options: this.purchaseSourceOptions, valueField: 'purchaseSource', nameField: 'purchaseSourceName' },
  442 + preferentialPolicy: { title: '是否享受优惠政策', options: this.yesNoOptions, valueField: 'preferentialPolicy', nameField: 'preferentialPolicyName' },
  443 + punishmentRecord: { title: '是否有被处罚记录', options: this.yesNoOptions, valueField: 'punishmentRecord', nameField: 'punishmentRecordName' },
  444 + futuresInvest: { title: '是否投资期货', options: this.yesNoOptions, valueField: 'futuresInvest', nameField: 'futuresInvestName' },
  445 + investNature: { title: '投资性质', options: this.investNatureOptions, valueField: 'investNature', nameField: 'investNatureName' },
  446 + badRecordPlanFail: { title: '是否有计划落空的不良记录', options: this.yesNoOptions, valueField: 'badRecordPlanFail', nameField: 'badRecordPlanFailName' },
  447 + planNotFulfilled: { title: '是否有计划履行不到位现象', options: this.yesNoOptions, valueField: 'planNotFulfilled', nameField: 'planNotFulfilledName' }
  448 + }
  449 + const cfg = map[field]
  450 + if (!cfg) return
  451 + const current = this.form[cfg.valueField]
  452 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  453 + this.sheet = {
  454 + ...this.sheet,
  455 + visible: true,
  456 + title: cfg.title,
  457 + options: cfg.options || [],
  458 + field,
  459 + value: match ? match.value : (current || '')
  460 + }
  461 + },
  462 + openMultiSheet(field) {
  463 + if (field !== 'companyNature') return
  464 + this.multiSheet = {
  465 + ...this.multiSheet,
  466 + visible: true,
  467 + title: '公司性质',
  468 + options: this.companyNatureOptions || [],
  469 + field,
  470 + value: this.form.companyNature || ''
  471 + }
  472 + },
  473 + onSheetConfirm({ value, label }) {
  474 + const field = this.sheet.field
  475 + if (field === 'purchaseSource') {
  476 + this.form.purchaseSource = value || ''
  477 + this.form.purchaseSourceName = label || ''
  478 + if (this.form.purchaseSource !== 'OTHER') this.form.purchaseSourceOther = ''
  479 + } else if (field === 'preferentialPolicy') {
  480 + this.form.preferentialPolicy = value || ''
  481 + this.form.preferentialPolicyName = label || ''
  482 + } else if (field === 'punishmentRecord') {
  483 + this.form.punishmentRecord = value || ''
  484 + this.form.punishmentRecordName = label || ''
  485 + } else if (field === 'futuresInvest') {
  486 + this.form.futuresInvest = value || ''
  487 + this.form.futuresInvestName = label || ''
  488 + } else if (field === 'investNature') {
  489 + this.form.investNature = value || ''
  490 + this.form.investNatureName = label || ''
  491 + } else if (field === 'badRecordPlanFail') {
  492 + this.form.badRecordPlanFail = value || ''
  493 + this.form.badRecordPlanFailName = label || ''
  494 + } else if (field === 'planNotFulfilled') {
  495 + this.form.planNotFulfilled = value || ''
  496 + this.form.planNotFulfilledName = label || ''
  497 + }
  498 + this.sheet.visible = false
  499 + },
  500 + onMultiSheetConfirm({ value }) {
  501 + const field = this.multiSheet.field
  502 + if (field === 'companyNature') {
  503 + const normalized = this.normalizeCompanyNature(value)
  504 + this.form.companyNature = normalized.value
  505 + this.form.companyNatureName = normalized.label
  506 + if (!this.showCompanyNatureOther) this.form.companyNatureOther = ''
  507 + }
  508 + this.multiSheet.visible = false
  509 + },
  510 + normalizeCompanyNature(valueStr) {
  511 + const selected = (valueStr ? String(valueStr).split(',').filter(Boolean) : [])
  512 + const group = ['IMPORT_DISMANTLE', 'INDUSTRY_MANUFACTURE', 'WELFARE_ENTERPRISE']
  513 + const groupSelected = selected.filter(v => group.includes(v))
  514 + let finalSelected = selected.slice(0)
  515 + if (groupSelected.length > 1) {
  516 + const keep = groupSelected[0]
  517 + finalSelected = finalSelected.filter(v => !group.includes(v) || v === keep)
  518 + }
  519 + const orderedValues = []
  520 + const orderedLabels = []
  521 + ;(this.companyNatureOptions || []).forEach(opt => {
  522 + const v = opt && opt.value != null ? String(opt.value) : ''
  523 + if (v && finalSelected.includes(v)) {
  524 + orderedValues.push(v)
  525 + orderedLabels.push(opt.label != null ? String(opt.label) : '')
  526 + }
  527 + })
  528 + return { value: orderedValues.join(','), label: orderedLabels.join(',') }
  529 + },
  530 + removeAttachment(idx) {
  531 + const list = Array.isArray(this.form.attachments) ? this.form.attachments.slice(0) : []
  532 + list.splice(idx, 1)
  533 + this.form.attachments = list
  534 + },
  535 + onAddAttachment(val) {
  536 + const payload = val || { id: '', name: '' }
  537 + if (!payload.id) return
  538 + const list = Array.isArray(this.form.attachments) ? this.form.attachments.slice(0) : []
  539 + list.push(payload)
  540 + this.form.attachments = list
  541 + this.newAttachment = { id: '', name: '' }
  542 + },
  543 + onAttachmentInput(idx, val) {
  544 + const list = Array.isArray(this.form.attachments) ? this.form.attachments.slice(0) : []
  545 + list[idx] = val || { id: '', name: '' }
  546 + this.form.attachments = list
  547 + },
  548 + validate() {
  549 + const phone = String(this.form.phone || '').trim()
  550 + if (phone && !/^1\d{10}$/.test(phone)) {
  551 + uni.showToast({ title: '电话请输入11位手机号', icon: 'none' })
  552 + return false
  553 + }
  554 + const year = String(this.form.cooperationStartYear || '').trim()
  555 + if (year && !/^\d{4}$/.test(year)) {
  556 + uni.showToast({ title: '合作年限请填写4位年份', icon: 'none' })
  557 + return false
  558 + }
  559 + return true
  560 + },
  561 + buildPayload() {
  562 + const payload = { ...this.form }
  563 + if (!this.showCompanyNatureOther) payload.companyNatureOther = ''
  564 + if (payload.purchaseSource !== 'OTHER') payload.purchaseSourceOther = ''
  565 + delete payload.companyNatureName
  566 + delete payload.purchaseSourceName
  567 + delete payload.preferentialPolicyName
  568 + delete payload.punishmentRecordName
  569 + delete payload.futuresInvestName
  570 + delete payload.investNatureName
  571 + delete payload.badRecordPlanFailName
  572 + delete payload.planNotFulfilledName
  573 + payload.attachments = (Array.isArray(payload.attachments) ? payload.attachments : []).filter(it => it && it.id)
  574 + return payload
  575 + },
  576 + async onSubmit() {
  577 + if (this.submitting) return
  578 + if (!this.validate()) return
  579 + this.submitting = true
  580 + const payload = this.buildPayload()
  581 + try {
  582 + await this.mockUpdate(payload)
  583 + uni.showToast({ title: '保存成功', icon: 'success' })
  584 + setTimeout(() => { uni.navigateBack() }, 300)
  585 + } catch (e) {
  586 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  587 + } finally {
  588 + this.submitting = false
  589 + }
  590 + },
  591 + async loadDetail() {
  592 + this.loading = true
  593 + try {
  594 + const data = await this.mockGetDetail(this.id)
  595 + const next = { ...this.form, ...(data || {}) }
  596 + next.id = next.id || this.id || ''
  597 + next.attachments = Array.isArray(next.attachments) ? next.attachments : []
  598 + this.form = next
  599 + this.refreshLabelFields()
  600 + } catch (e) {
  601 + uni.showToast({ title: '加载失败', icon: 'none' })
  602 + } finally {
  603 + this.loading = false
  604 + }
  605 + },
  606 + refreshLabelFields() {
  607 + this.form.companyNatureName = this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  608 + this.form.purchaseSourceName = this.labelOf(this.purchaseSourceOptions, this.form.purchaseSource)
  609 + this.form.preferentialPolicyName = this.labelOf(this.yesNoOptions, this.form.preferentialPolicy)
  610 + this.form.punishmentRecordName = this.labelOf(this.yesNoOptions, this.form.punishmentRecord)
  611 + this.form.futuresInvestName = this.labelOf(this.yesNoOptions, this.form.futuresInvest)
  612 + this.form.investNatureName = this.labelOf(this.investNatureOptions, this.form.investNature)
  613 + this.form.badRecordPlanFailName = this.labelOf(this.yesNoOptions, this.form.badRecordPlanFail)
  614 + this.form.planNotFulfilledName = this.labelOf(this.yesNoOptions, this.form.planNotFulfilled)
  615 + },
  616 + labelOf(options, value) {
  617 + const v = value == null ? '' : String(value)
  618 + if (!v) return ''
  619 + const found = (options || []).find(o => String(o.value) === v)
  620 + return found ? String(found.label) : v
  621 + },
  622 + labelsOf(options, csv) {
  623 + const v = csv == null ? '' : String(csv)
  624 + if (!v) return ''
  625 + const parts = v.split(',').filter(Boolean)
  626 + if (!parts.length) return ''
  627 + const labels = []
  628 + ;(options || []).forEach(opt => {
  629 + const ov = opt && opt.value != null ? String(opt.value) : ''
  630 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  631 + })
  632 + return labels.filter(Boolean).join(',') || ''
  633 + },
  634 + mockGetDetail(id) {
  635 + return new Promise(resolve => {
  636 + const stored = this.tryLoadFromStorage(id)
  637 + if (stored) return setTimeout(() => resolve(stored), 180)
  638 + setTimeout(() => resolve(this.buildMockDetail(id)), 180)
  639 + })
  640 + },
  641 + tryLoadFromStorage(id) {
  642 + try {
  643 + const raw = uni.getStorageSync('DOMESTIC_TRADE_RECORDS')
  644 + const arr = Array.isArray(raw) ? raw : (raw && Array.isArray(raw.list) ? raw.list : [])
  645 + if (!id) return arr && arr[0] ? arr[0] : null
  646 + const found = (arr || []).find(it => it && String(it.id || '') === String(id))
  647 + return found || null
  648 + } catch (e) {
  649 + return null
  650 + }
  651 + },
  652 + buildMockDetail(id) {
  653 + const now = new Date()
  654 + const createDate = this.formatDate(now)
  655 + return {
  656 + id: id || '1',
  657 + companyName: '华东商贸有限公司1',
  658 + companyNature: 'RECYCLE,OTHER',
  659 + companyNatureOther: '再生资源综合回收',
  660 + bankName: '中国工商银行上海分行',
  661 + bankAccount: '6222020202020202',
  662 + registeredCapital: '500',
  663 + annualTurnover: '2600',
  664 + legalRepresentative: '张三',
  665 + companyFoundedDate: '2018-06-01',
  666 + address: '上海市浦东新区示例路 88 号',
  667 + businessOwner: '李四',
  668 + position: '总经理',
  669 + phone: '13800000000',
  670 + fax: '021-88888888',
  671 + legalBusinessRelation: '亲属',
  672 + liquidWorkingCapital: '流动资金 300 万;购销结算期限 30 天;债权债务情况正常',
  673 + fixedAssets: '厂房产权自有 2000㎡;主要设备投资 800 万;仓库自有 1200㎡;正常库存量 300 吨',
  674 + purchaseSituation: '主要品种:铜、铁;收购量:月均 1200 吨;上年度利润:铜 120 万,铁 80 万;入库流程规范',
  675 + purchaseSource: 'OTHER',
  676 + purchaseSourceOther: '本地回收站合作渠道',
  677 + productionSituation: '产品:再生铜;产能:月均 800 吨;能耗:电 40 万度/月',
  678 + salesSituation: '渠道:长期客户+现货;回款方式:承兑/转账;结算期限:30-60 天',
  679 + preferentialPolicy: 'NO',
  680 + preferentialPolicyDetail: '',
  681 + punishmentRecord: 'NO',
  682 + scopeMatch: '相符',
  683 + futuresInvest: 'YES',
  684 + investNature: 'HEDGE_MAIN',
  685 + lastYearFuturesProfitLoss: '盈利 15 万',
  686 + cooperationStartYear: '2021',
  687 + mainOperationMode: '现货+月度计划',
  688 + badRecordPlanFail: 'NO',
  689 + planNotFulfilled: 'NO',
  690 + operationNorms: '账务按月对账;开票品名一致;出库流程规范;运输发票齐全',
  691 + commonMaterialIssues: '含杂偏高、含水偏高',
  692 + otherCooperationIssues: '暂无',
  693 + createDate,
  694 + reviewDate: '',
  695 + attachments: [
  696 + { id: 'mock-file-1', name: '资信调查表.pdf' },
  697 + { id: 'mock-file-2', name: '营业执照.jpg' }
  698 + ]
  699 + }
  700 + },
  701 + mockUpdate(payload) {
  702 + return new Promise(resolve => {
  703 + setTimeout(() => {
  704 + const list = this.loadStorageList()
  705 + const id = payload && payload.id ? String(payload.id) : (this.id ? String(this.id) : String(Date.now()))
  706 + const next = { ...payload, id }
  707 + const idx = list.findIndex(it => it && String(it.id || '') === id)
  708 + if (idx >= 0) list.splice(idx, 1, next)
  709 + else list.unshift(next)
  710 + uni.setStorageSync('DOMESTIC_TRADE_RECORDS', list)
  711 + resolve({ success: true })
  712 + }, 350)
  713 + })
  714 + },
  715 + loadStorageList() {
  716 + try {
  717 + const raw = uni.getStorageSync('DOMESTIC_TRADE_RECORDS')
  718 + return Array.isArray(raw) ? raw.slice(0) : (raw && Array.isArray(raw.list) ? raw.list.slice(0) : [])
  719 + } catch (e) {
  720 + return []
  721 + }
  722 + },
  723 + formatDate(d) {
  724 + const y = d.getFullYear()
  725 + const m = String(d.getMonth() + 1).padStart(2, '0')
  726 + const da = String(d.getDate()).padStart(2, '0')
  727 + return `${y}-${m}-${da}`
  728 + }
  729 + }
  730 +}
  731 +</script>
  732 +
  733 +<style lang="scss" scoped>
  734 +.page {
  735 + display: flex;
  736 + flex-direction: column;
  737 + height: 100%;
  738 +}
  739 +
  740 +.scroll {
  741 + flex: 1;
  742 + padding: 12rpx 0 160rpx;
  743 +}
  744 +
  745 +.footer {
  746 + position: fixed;
  747 + left: 0;
  748 + right: 0;
  749 + bottom: 0;
  750 + padding: 32rpx;
  751 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  752 + background: #fff;
  753 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  754 + z-index: 10;
  755 +
  756 + .btn {
  757 + height: 80rpx;
  758 + line-height: 80rpx;
  759 + border-radius: 12rpx;
  760 + font-size: 32rpx;
  761 + }
  762 +
  763 + .submit {
  764 + background: $theme-primary;
  765 + color: #fff;
  766 + }
  767 +}
  768 +
  769 +.title-header {
  770 + display: flex;
  771 + align-items: center;
  772 + padding: 24rpx 32rpx 12rpx;
  773 + background-color: #ffffff;
  774 + .title-header_icon {
  775 + width: 36rpx;
  776 + height: 36rpx;
  777 + margin-right: 12rpx;
  778 + }
  779 +
  780 + span {
  781 + font-size: 34rpx;
  782 + font-weight: 600;
  783 + color: rgba(0, 0, 0, 0.9);
  784 + }
  785 +}
  786 +
  787 +.mgb10 {
  788 + margin-bottom: 20rpx;
  789 +}
  790 +
  791 +.amount-row {
  792 + display: flex;
  793 + align-items: center;
  794 + gap: 12rpx;
  795 +
  796 + .unit, .prefix, .suffix {
  797 + font-size: 28rpx;
  798 + color: rgba(0, 0, 0, 0.6);
  799 + white-space: nowrap;
  800 + }
  801 +}
  802 +
  803 +.attach-box {
  804 + display: flex;
  805 + flex-direction: column;
  806 + align-items: flex-end;
  807 + gap: 16rpx;
  808 + width: 100%;
  809 +}
  810 +
  811 +.attach-row {
  812 + width: 100%;
  813 + display: flex;
  814 + justify-content: flex-end;
  815 + align-items: center;
  816 + gap: 20rpx;
  817 +}
  818 +
  819 +.attach-del {
  820 + font-size: 28rpx;
  821 + color: #D54941;
  822 +}
  823 +
  824 +::v-deep .uni-list {
  825 + .uni-easyinput {
  826 + display: flex;
  827 +
  828 + .uni-input-input {
  829 + color: rgba(0, 0, 0, 0.9);
  830 + }
  831 + }
  832 +
  833 + .uni-input-placeholder {
  834 + z-index: 1;
  835 + }
  836 +
  837 + .uni-input-input {
  838 + background-color: #ffffff;
  839 + }
  840 +
  841 + background: transparent;
  842 +
  843 + &-item {
  844 + &__extra-text {
  845 + font-size: 32rpx;
  846 + }
  847 +
  848 + &__content-title {
  849 + font-size: 32rpx;
  850 + color: rgba(0, 0, 0, 0.9);
  851 + }
  852 +
  853 + &__container {
  854 + padding: 32rpx;
  855 +
  856 + .uni-easyinput {
  857 + &__placeholder-class {
  858 + font-size: 32rpx;
  859 + color: rgba(0, 0, 0, 0.4);
  860 + }
  861 +
  862 + &__content {
  863 + border: none;
  864 + background-color: #ffffff !important;
  865 +
  866 + &-input {
  867 + padding-left: 0 !important;
  868 + height: 48rpx;
  869 + line-height: 48rpx;
  870 + font-size: 32rpx;
  871 + }
  872 +
  873 + .content-clear-icon {
  874 + font-size: 44rpx !important;
  875 + }
  876 + }
  877 + }
  878 +
  879 + .item-title,
  880 + .uni-list-item__content {
  881 + flex: none;
  882 + min-height: 48rpx;
  883 + line-height: 48rpx;
  884 + font-size: 32rpx;
  885 + position: relative;
  886 + width: 210rpx;
  887 + margin-right: 32rpx;
  888 + color: rgba(0, 0, 0, 0.9);
  889 +
  890 + .required {
  891 + color: red;
  892 + position: absolute;
  893 + top: 50%;
  894 + transform: translateY(-50%);
  895 + left: -16rpx;
  896 + }
  897 + }
  898 + }
  899 +
  900 + &.select-item {
  901 + &.is-empty {
  902 + .uni-list-item__extra-text {
  903 + color: rgba(0, 0, 0, 0.4) !important;
  904 + }
  905 + }
  906 +
  907 + &.is-filled {
  908 + .uni-list-item__extra-text {
  909 + color: rgba(0, 0, 0, 0.9) !important;
  910 + }
  911 + }
  912 + }
  913 +
  914 + &.mgb10 {
  915 + margin-bottom: 20rpx;
  916 + }
  917 + }
  918 +}
  919 +</style>
... ...
... ... @@ -143,6 +143,16 @@ export default {
143 143 ],
144 144 },
145 145 {
  146 + title: '销售管理',
  147 + items: [{
  148 + text: '内贸合同',
  149 + icon: '/static/images/index/order_list.png',
  150 + link: '/pages/domestic_trade/index',
  151 + name: 'DomesticTrade'
  152 + }]
  153 +
  154 + },
  155 + {
146 156 title: '订货单管理',
147 157 items: [{
148 158 text: '订货单列表',
... ...