Commit a07513c543cb2ba308eb9d160087d265e5152b89

Authored by gesilong
2 parents 51085144 f5b84923

Merge branch 'cjerp-2.0' into test_cjerp

  1 +import request from '@/utils/request'
  2 +import { ContentTypeEnum } from '@/utils/httpEnum'
  3 +
  4 +export function domesticCustomerCreditQueryApi(params) {
  5 + return request({
  6 + url: '/procurement/domesticCustomerCredit/query',
  7 + method: 'get',
  8 + params
  9 + })
  10 +}
  11 +
  12 +export function domesticCustomerCreditSaveApi(data) {
  13 + return request({
  14 + url: '/procurement/domesticCustomerCredit',
  15 + method: 'post',
  16 + data,
  17 + contentType: ContentTypeEnum.JSON
  18 + })
  19 +}
  20 +
  21 +export function domesticCustomerCreditGetApi(id) {
  22 + return request({
  23 + url: '/procurement/domesticCustomerCredit/get',
  24 + method: 'get',
  25 + params: { id }
  26 + })
  27 +}
  28 +
  29 +export function domesticCustomerCreditGetExamineByIdApi(id) {
  30 + return request({
  31 + url: '/procurement/domesticCustomerCredit/getExamineById',
  32 + method: 'get',
  33 + params: { id }
  34 + })
  35 +}
  36 +
  37 +export function domesticCustomerCreditCancelApi(id) {
  38 + return request({
  39 + url: '/procurement/domesticCustomerCredit/cancel',
  40 + method: 'get',
  41 + params: { id }
  42 + })
  43 +}
  44 +
  45 +export function getPurchaseDeptApi() {
  46 + return request({
  47 + url: '/system/dept/getPurchaseDept',
  48 + method: 'get'
  49 + })
  50 +}
  1 +import request from '@/utils/request'
  2 +import { ContentTypeEnum } from '@/utils/httpEnum'
  3 +
  4 +export function foreignCustomerCreditQueryApi(params) {
  5 + return request({
  6 + url: '/procurement/foreignCustomerCredit/query',
  7 + method: 'get',
  8 + params
  9 + })
  10 +}
  11 +
  12 +export function foreignCustomerCreditSaveApi(data) {
  13 + return request({
  14 + url: '/procurement/foreignCustomerCredit',
  15 + method: 'post',
  16 + data,
  17 + contentType: ContentTypeEnum.JSON
  18 + })
  19 +}
  20 +
  21 +export function foreignCustomerCreditGetApi(id) {
  22 + return request({
  23 + url: '/procurement/foreignCustomerCredit/get',
  24 + method: 'get',
  25 + params: { id }
  26 + })
  27 +}
  28 +
  1 +import request from '@/utils/request'
  2 +import { ContentTypeEnum } from '@/utils/httpEnum'
  3 +
  4 +export function foreignTradeCreditQueryApi(params) {
  5 + return request({
  6 + url: '/procurement/foreignTradeCredit/query',
  7 + method: 'get',
  8 + params
  9 + })
  10 +}
  11 +
  12 +export function foreignTradeCreditSaveApi(data) {
  13 + return request({
  14 + url: '/procurement/foreignTradeCredit',
  15 + method: 'post',
  16 + data,
  17 + contentType: ContentTypeEnum.JSON
  18 + })
  19 +}
  20 +
  21 +export function foreignTradeCreditGetApi(id) {
  22 + return request({
  23 + url: '/procurement/foreignTradeCredit/get',
  24 + method: 'get',
  25 + params: { id }
  26 + })
  27 +}
  28 +
  29 +export function foreignTradeCreditCancelApi(id) {
  30 + return request({
  31 + url: '/procurement/foreignTradeCredit/cancel',
  32 + method: 'get',
  33 + params: { id }
  34 + })
  35 +}
  36 +
  37 +export function foreignTradeCreditGetExamineByIdApi(id) {
  38 + return request({
  39 + url: '/procurement/foreignTradeCredit/getExamineById',
  40 + method: 'get',
  41 + params: { id }
  42 + })
  43 +}
  44 +
  45 +export function getPurchaseDeptApi() {
  46 + return request({
  47 + url: '/system/dept/getPurchaseDept',
  48 + method: 'get'
  49 + })
  50 +}
@@ -212,6 +212,70 @@ @@ -212,6 +212,70 @@
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 + {
  247 + "path": "pages/foreign_trade/index",
  248 + "style": {
  249 + "navigationBarTitleText": "外贸供应商资信列表",
  250 + "navigationBarBackgroundColor": "#ffffff",
  251 + "navigationBarTextStyle": "black"
  252 + }
  253 + },
  254 + {
  255 + "path": "pages/foreign_trade/add",
  256 + "style": {
  257 + "navigationBarTitleText": "新增外贸供应商资信",
  258 + "navigationBarBackgroundColor": "#ffffff",
  259 + "navigationBarTextStyle": "black"
  260 + }
  261 + },
  262 + {
  263 + "path": "pages/foreign_trade/modify",
  264 + "style": {
  265 + "navigationBarTitleText": "编辑外贸供应商资信",
  266 + "navigationBarBackgroundColor": "#ffffff",
  267 + "navigationBarTextStyle": "black"
  268 + }
  269 + },
  270 + {
  271 + "path": "pages/foreign_trade/detail",
  272 + "style": {
  273 + "navigationBarTitleText": "外贸供应商资信详情",
  274 + "navigationBarBackgroundColor": "#ffffff",
  275 + "navigationBarTextStyle": "black"
  276 + }
  277 + },
  278 + {
215 "path": "pages/order_list/index", 279 "path": "pages/order_list/index",
216 "style": { 280 "style": {
217 "navigationBarTitleText": "订货单列表", 281 "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.unitName" placeholder="请输入单位名称" :inputBorder="false" />
  13 + </template>
  14 + </uni-list-item>
  15 + <uni-list-item title="客户简称">
  16 + <template v-slot:footer>
  17 + <uni-easyinput v-model="form.customerShortName" placeholder="请输入客户简称" :inputBorder="false" />
  18 + </template>
  19 + </uni-list-item>
  20 + <uni-list-item class="select-item" :class="form.companyNatureName ? 'is-filled' : 'is-empty'" clickable
  21 + @click="openMultiSheet('companyNature')" :rightText="displayLabel('companyNatureName')" showArrow>
  22 + <template v-slot:body>
  23 + <view class="item-title"><text>公司性质</text></view>
  24 + </template>
  25 + </uni-list-item>
  26 + <uni-list-item v-if="showCompanyNatureOther" class="mgb10" title="其他">
  27 + <template v-slot:footer>
  28 + <uni-easyinput v-model="form.companyNatureOther" 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.bankName" 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.bankAccount" placeholder="请输入账号" :inputBorder="false" />
  41 + </template>
  42 + </uni-list-item>
  43 +
  44 + <uni-list-item class="amount-item">
  45 + <template v-slot:body>
  46 + <view class="item-title"><text>注册资金</text></view>
  47 + </template>
  48 + <template v-slot:footer>
  49 + <view class="amount-row">
  50 + <uni-easyinput type="digit" v-model="form.registeredCapital" placeholder="请输入" :inputBorder="false" />
  51 + <text class="unit">万元</text>
  52 + </view>
  53 + </template>
  54 + </uni-list-item>
  55 +
  56 + <uni-list-item title="法人代表">
  57 + <template v-slot:footer>
  58 + <uni-easyinput v-model="form.legalRepresentative" placeholder="请输入法人代表" :inputBorder="false" />
  59 + </template>
  60 + </uni-list-item>
  61 +
  62 + <uni-list-item title="公司成立时间">
  63 + <template v-slot:footer>
  64 + <uni-datetime-picker type="date" v-model="form.companyEstablishedTime" />
  65 + </template>
  66 + </uni-list-item>
  67 +
  68 + <uni-list-item title="地址">
  69 + <template v-slot:footer>
  70 + <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
  71 + </template>
  72 + </uni-list-item>
  73 +
  74 + <uni-list-item title="业务负责人">
  75 + <template v-slot:footer>
  76 + <uni-easyinput v-model="form.businessPrincipal" placeholder="请输入业务负责人" :inputBorder="false" />
  77 + </template>
  78 + </uni-list-item>
  79 +
  80 + <uni-list-item title="职务">
  81 + <template v-slot:footer>
  82 + <uni-easyinput v-model="form.businessPrincipalPosition" placeholder="请输入职务" :inputBorder="false" />
  83 + </template>
  84 + </uni-list-item>
  85 +
  86 + <uni-list-item title="电话">
  87 + <template v-slot:footer>
  88 + <uni-easyinput type="number" v-model="form.businessPrincipalPhone" placeholder="请输入手机号码" :inputBorder="false" />
  89 + </template>
  90 + </uni-list-item>
  91 +
  92 + <uni-list-item class="mgb10" title="法人与业务负责人关系">
  93 + <template v-slot:footer>
  94 + <uni-easyinput v-model="form.legalBusinessRelation" placeholder="请输入" :inputBorder="false" />
  95 + </template>
  96 + </uni-list-item>
  97 +
  98 + <view class="title-header">
  99 + <image class="title-header_icon" src="/static/images/title.png" />
  100 + <span>资产状况</span>
  101 + </view>
  102 +
  103 + <uni-list-item title="生产厂房及办公楼产权">
  104 + <template v-slot:footer>
  105 + <uni-easyinput v-model="form.factoryOfficeProperty" placeholder="请输入" :inputBorder="false" />
  106 + </template>
  107 + </uni-list-item>
  108 +
  109 + <uni-list-item title="生产厂房及办公楼面积">
  110 + <template v-slot:footer>
  111 + <uni-easyinput v-model="form.factoryOfficeArea" placeholder="请输入" :inputBorder="false" />
  112 + </template>
  113 + </uni-list-item>
  114 +
  115 + <uni-list-item title="仓库或货场产权">
  116 + <template v-slot:footer>
  117 + <uni-easyinput v-model="form.warehouseYardProperty" placeholder="请输入" :inputBorder="false" />
  118 + </template>
  119 + </uni-list-item>
  120 +
  121 + <uni-list-item title="仓库或货场产权面积">
  122 + <template v-slot:footer>
  123 + <uni-easyinput v-model="form.warehouseYardArea" placeholder="请输入" :inputBorder="false" />
  124 + </template>
  125 + </uni-list-item>
  126 +
  127 + <uni-list-item title="主要生产设备">
  128 + <template v-slot:footer>
  129 + <uni-easyinput type="textarea" v-model="form.mainEquipment" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  130 + </template>
  131 + </uni-list-item>
  132 +
  133 + <uni-list-item class="mgb10" title="正常库存量">
  134 + <template v-slot:footer>
  135 + <uni-easyinput v-model="form.normalInventory" placeholder="请输入" :inputBorder="false" />
  136 + </template>
  137 + </uni-list-item>
  138 +
  139 + <view class="title-header">
  140 + <image class="title-header_icon" src="/static/images/title.png" />
  141 + <span>生产经营环节风险调查</span>
  142 + </view>
  143 +
  144 + <uni-list-item title="主要品种">
  145 + <template v-slot:footer>
  146 + <uni-easyinput v-model="form.mainVarieties" placeholder="请输入" :inputBorder="false" />
  147 + </template>
  148 + </uni-list-item>
  149 +
  150 + <uni-list-item title="月度收购量">
  151 + <template v-slot:footer>
  152 + <uni-easyinput v-model="form.monthlyPurchaseVolume" placeholder="请输入" :inputBorder="false" />
  153 + </template>
  154 + </uni-list-item>
  155 +
  156 + <uni-list-item class="select-item" :class="form.purchaseSource ? 'is-filled' : 'is-empty'" clickable
  157 + @click="openSheet('purchaseSource')" :rightText="displayLabel('purchaseSource')" showArrow>
  158 + <template v-slot:body>
  159 + <view class="item-title"><text>收购来源</text></view>
  160 + </template>
  161 + </uni-list-item>
  162 +
  163 + <uni-list-item title="入库品名">
  164 + <template v-slot:footer>
  165 + <uni-easyinput v-model="form.stockInProductName" placeholder="请输入" :inputBorder="false" />
  166 + </template>
  167 + </uni-list-item>
  168 +
  169 + <uni-list-item title="产品名称">
  170 + <template v-slot:footer>
  171 + <uni-easyinput v-model="form.productName" placeholder="请输入" :inputBorder="false" />
  172 + </template>
  173 + </uni-list-item>
  174 +
  175 + <uni-list-item title="产能">
  176 + <template v-slot:footer>
  177 + <uni-easyinput v-model="form.capacity" placeholder="请输入" :inputBorder="false" />
  178 + </template>
  179 + </uni-list-item>
  180 +
  181 + <uni-list-item title="销售渠道">
  182 + <template v-slot:footer>
  183 + <uni-easyinput v-model="form.salesChannel" placeholder="请输入" :inputBorder="false" />
  184 + </template>
  185 + </uni-list-item>
  186 +
  187 + <uni-list-item class="select-item" :class="form.operationMode ? 'is-filled' : 'is-empty'" clickable
  188 + @click="openSheet('operationMode')" :rightText="displayLabel('operationMode')" showArrow>
  189 + <template v-slot:body>
  190 + <view class="item-title"><text>操作方式</text></view>
  191 + </template>
  192 + </uni-list-item>
  193 +
  194 + <uni-list-item class="select-item" :class="form.hasPreferentialPolicy === true || form.hasPreferentialPolicy === false ? 'is-filled' : 'is-empty'" clickable
  195 + @click="openSheet('hasPreferentialPolicy')" :rightText="displayLabel('hasPreferentialPolicy')" showArrow>
  196 + <template v-slot:body>
  197 + <view class="item-title"><text>是否享有优惠政策</text></view>
  198 + </template>
  199 + </uni-list-item>
  200 +
  201 + <uni-list-item class="select-item" :class="form.investInFutures === true || form.investInFutures === false ? 'is-filled' : 'is-empty'" clickable
  202 + @click="openSheet('investInFutures')" :rightText="displayLabel('investInFutures')" showArrow>
  203 + <template v-slot:body>
  204 + <view class="item-title"><text>是否投资期货</text></view>
  205 + </template>
  206 + </uni-list-item>
  207 +
  208 + <uni-list-item class="select-item" :class="form.hasPenaltyRecord === true || form.hasPenaltyRecord === false ? 'is-filled' : 'is-empty'" clickable
  209 + @click="openSheet('hasPenaltyRecord')" :rightText="displayLabel('hasPenaltyRecord')" showArrow>
  210 + <template v-slot:body>
  211 + <view class="item-title"><text>是否有被处罚记录</text></view>
  212 + </template>
  213 + </uni-list-item>
  214 +
  215 + <uni-list-item class="select-item" :class="form.businessScopeMatch === true || form.businessScopeMatch === false ? 'is-filled' : 'is-empty'" clickable
  216 + @click="openSheet('businessScopeMatch')" :rightText="displayLabel('businessScopeMatch')" showArrow>
  217 + <template v-slot:body>
  218 + <view class="item-title"><text>实际经营范围与法定经营范围是否相符</text></view>
  219 + </template>
  220 + </uni-list-item>
  221 +
  222 + <uni-list-item title="常见料质问题">
  223 + <template v-slot:footer>
  224 + <uni-easyinput type="textarea" v-model="form.commonMaterialIssue" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  225 + </template>
  226 + </uni-list-item>
  227 +
  228 + <uni-list-item class="mgb10" title="合作中的其它问题">
  229 + <template v-slot:footer>
  230 + <uni-easyinput type="textarea" v-model="form.otherIssue" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  231 + </template>
  232 + </uni-list-item>
  233 +
  234 + <view class="title-header">
  235 + <image class="title-header_icon" src="/static/images/title.png" />
  236 + <span>与我司的合作状况</span>
  237 + </view>
  238 +
  239 + <uni-list-item title="首次合作年份">
  240 + <template v-slot:footer>
  241 + <uni-easyinput type="digit" v-model="form.firstCooperationYear" placeholder="请输入4位年份" :inputBorder="false" />
  242 + </template>
  243 + </uni-list-item>
  244 +
  245 + <uni-list-item class="select-item" :class="form.isNewDevelopment ? 'is-filled' : 'is-empty'" clickable
  246 + @click="openSheet('isNewDevelopment')" :rightText="displayLabel('isNewDevelopment')" showArrow>
  247 + <template v-slot:body>
  248 + <view class="item-title"><text>是否新开发</text></view>
  249 + </template>
  250 + </uni-list-item>
  251 +
  252 + <uni-list-item class="select-item" :class="form.hasFailedPlanRecord === true || form.hasFailedPlanRecord === false ? 'is-filled' : 'is-empty'" clickable
  253 + @click="openSheet('hasFailedPlanRecord')" :rightText="displayLabel('hasFailedPlanRecord')" showArrow>
  254 + <template v-slot:body>
  255 + <view class="item-title"><text>是否有计划落空的不良记录</text></view>
  256 + </template>
  257 + </uni-list-item>
  258 + <uni-list-item class="select-item" :class="form.hasPlanPerformanceIssue === true || form.hasPlanPerformanceIssue === false ? 'is-filled' : 'is-empty'" clickable
  259 + @click="openSheet('hasPlanPerformanceIssue')" :rightText="displayLabel('hasPlanPerformanceIssue')" showArrow>
  260 + <template v-slot:body>
  261 + <view class="item-title"><text>是否有计划履行不到位现象</text></view>
  262 + </template>
  263 + </uni-list-item>
  264 +
  265 + <uni-list-item title="进销账务如何处理">
  266 + <template v-slot:footer>
  267 + <uni-easyinput type="textarea" v-model="form.accountingProcess" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  268 + </template>
  269 + </uni-list-item>
  270 +
  271 + <uni-list-item class="select-item" :class="form.invoiceNameMatch === true || form.invoiceNameMatch === false ? 'is-filled' : 'is-empty'" clickable
  272 + @click="openSheet('invoiceNameMatch')" :rightText="displayLabel('invoiceNameMatch')" showArrow>
  273 + <template v-slot:body>
  274 + <view class="item-title"><text>开票品名与出库单品名是否一致</text></view>
  275 + </template>
  276 + </uni-list-item>
  277 +
  278 + <uni-list-item class="select-item" :class="form.outboundProcessStandard === true || form.outboundProcessStandard === false ? 'is-filled' : 'is-empty'" clickable
  279 + @click="openSheet('outboundProcessStandard')" :rightText="displayLabel('outboundProcessStandard')" showArrow>
  280 + <template v-slot:body>
  281 + <view class="item-title"><text>出库流程是否规范</text></view>
  282 + </template>
  283 + </uni-list-item>
  284 +
  285 + <uni-list-item class="mgb10" title="运输方式">
  286 + <template v-slot:footer>
  287 + <uni-easyinput v-model="form.transportMode" placeholder="请输入" :inputBorder="false" />
  288 + </template>
  289 + </uni-list-item>
  290 +
  291 + <view class="title-header">
  292 + <image class="title-header_icon" src="/static/images/title.png" />
  293 + <span>其他</span>
  294 + </view>
  295 +
  296 + <uni-list-item title="资信调查人">
  297 + <template v-slot:footer>
  298 + <uni-easyinput v-model="form.investigatorName" disabled placeholder="" :inputBorder="false" />
  299 + </template>
  300 + </uni-list-item>
  301 +
  302 + <uni-list-item title="采购处">
  303 + <template v-slot:footer>
  304 + <uni-easyinput v-model="form.purchaseDepartmentName" disabled placeholder="" :inputBorder="false" />
  305 + </template>
  306 + </uni-list-item>
  307 +
  308 + <uni-list-item title="评审有效期">
  309 + <template v-slot:footer>
  310 + <uni-datetime-picker type="date" v-model="form.reviewValidUntil" />
  311 + </template>
  312 + </uni-list-item>
  313 +
  314 + <uni-list-item class="mgb10" title="附件">
  315 + <template v-slot:footer>
  316 + <view class="attach-box">
  317 + <view v-for="(f, idx) in attachmentFiles" :key="idx" class="attach-row">
  318 + <FileUpload :value="f" @input="onAttachmentInput(idx, $event)" />
  319 + <text class="attach-del" @click.stop="removeAttachment(idx)">删除</text>
  320 + </view>
  321 + <view class="attach-row">
  322 + <FileUpload :value="newAttachment" @input="onAddAttachment" />
  323 + </view>
  324 + </view>
  325 + </template>
  326 + </uni-list-item>
  327 + </uni-list>
  328 + </scroll-view>
  329 +
  330 + <view class="footer">
  331 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '提交中...' : '提交' }}</button>
  332 + </view>
  333 +
  334 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  335 + @confirm="onSheetConfirm" />
  336 + <MultiSelectSheet :visible.sync="multiSheet.visible" :title="multiSheet.title" :options="multiSheet.options"
  337 + v-model="multiSheet.value" @confirm="onMultiSheetConfirm" />
  338 + </view>
  339 +</template>
  340 +
  341 +<script>
  342 +import FileUpload from '@/components/file-upload/index.vue'
  343 +import SingleSelectSheet from '@/components/single-select/index.vue'
  344 +import MultiSelectSheet from '@/components/multi-select/index.vue'
  345 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  346 +import { domesticCustomerCreditSaveApi, getPurchaseDeptApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  347 +
  348 +export default {
  349 + name: 'DomesticTradeAdd',
  350 + components: { FileUpload, SingleSelectSheet, MultiSelectSheet },
  351 + data() {
  352 + return {
  353 + submitting: false,
  354 + newAttachment: { id: '', name: '' },
  355 + attachmentFiles: [],
  356 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  357 + multiSheet: { visible: false, title: '', options: [], field: '', value: '' },
  358 + dicOptions: {
  359 + COMPANY_NATURE: [],
  360 + DEVELOP_NEW: [],
  361 + OPERATION_METHOD: [],
  362 + PURCHASE_SOURCE: []
  363 + },
  364 + yesNoOptions: [
  365 + { label: '是', value: true },
  366 + { label: '否', value: false }
  367 + ],
  368 + companyNatureOptions: [],
  369 + operationMethodOptions: [],
  370 + developNewOptions: [],
  371 + purchaseSourceOptions: [],
  372 + form: {
  373 + unitName: '',
  374 + customerShortName: '',
  375 + companyNature: '',
  376 + companyNatureName: '',
  377 + companyNatureOther: '',
  378 + bankName: '',
  379 + bankAccount: '',
  380 + registeredCapital: '',
  381 + legalRepresentative: '',
  382 + companyEstablishedTime: '',
  383 + address: '',
  384 + businessPrincipal: '',
  385 + businessPrincipalPosition: '',
  386 + businessPrincipalPhone: '',
  387 + legalBusinessRelation: '',
  388 + factoryOfficeProperty: '',
  389 + factoryOfficeArea: '',
  390 + warehouseYardProperty: '',
  391 + warehouseYardArea: '',
  392 + mainEquipment: '',
  393 + normalInventory: '',
  394 + mainVarieties: '',
  395 + monthlyPurchaseVolume: '',
  396 + purchaseSource: '',
  397 + stockInProductName: '',
  398 + productName: '',
  399 + capacity: '',
  400 + salesChannel: '',
  401 + hasPreferentialPolicy: null,
  402 + investInFutures: null,
  403 + hasPenaltyRecord: null,
  404 + businessScopeMatch: null,
  405 + commonMaterialIssue: '',
  406 + otherIssue: '',
  407 + firstCooperationYear: '',
  408 + isNewDevelopment: '',
  409 + operationMode: '',
  410 + hasFailedPlanRecord: null,
  411 + hasPlanPerformanceIssue: null,
  412 + accountingProcess: '',
  413 + invoiceNameMatch: null,
  414 + outboundProcessStandard: null,
  415 + transportMode: '',
  416 + attachmentFileIds: '',
  417 + attachmentFileNames: '',
  418 + investigatorId: '',
  419 + investigatorName: '',
  420 + purchaseDepartment: '',
  421 + purchaseDepartmentName: '',
  422 + reviewValidUntil: ''
  423 + }
  424 + }
  425 + },
  426 + created() {
  427 + this.loadDicData()
  428 + this.loadPurchaseDeptOptions()
  429 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  430 + this.form.investigatorId = u && u.id ? String(u.id) : ''
  431 + this.form.investigatorName = u && u.name ? String(u.name) : ''
  432 + },
  433 + computed: {
  434 + showCompanyNatureOther() {
  435 + const v = String(this.form.companyNature || '')
  436 + return v.split(',').includes('OTHER')
  437 + }
  438 + },
  439 + methods: {
  440 + async loadDicData() {
  441 + try {
  442 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  443 + const next = {
  444 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  445 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  446 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  447 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  448 + }
  449 + this.dicOptions = next
  450 + this.companyNatureOptions = this.dicToSheetOptions(next.COMPANY_NATURE)
  451 + this.developNewOptions = this.dicToSheetOptions(next.DEVELOP_NEW)
  452 + this.operationMethodOptions = this.dicToSheetOptions(next.OPERATION_METHOD)
  453 + this.purchaseSourceOptions = this.dicToSheetOptions(next.PURCHASE_SOURCE)
  454 + this.form.companyNatureName = this.labelsOfOptions(this.companyNatureOptions, this.form.companyNature)
  455 + } catch (e) {
  456 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  457 + this.companyNatureOptions = []
  458 + this.developNewOptions = []
  459 + this.operationMethodOptions = []
  460 + this.purchaseSourceOptions = []
  461 + uni.showToast({ title: '字典加载失败', icon: 'none' })
  462 + }
  463 + },
  464 + async loadPurchaseDeptOptions() {
  465 + try {
  466 + const res = await getPurchaseDeptApi()
  467 + const data = (res && res.data) ? res.data : {}
  468 + this.form.purchaseDepartment = data && data.id != null ? String(data.id) : ''
  469 + this.form.purchaseDepartmentName = data && data.name != null ? String(data.name) : ''
  470 + } catch (e) {
  471 + this.form.purchaseDepartment = ''
  472 + this.form.purchaseDepartmentName = ''
  473 + }
  474 + },
  475 + dicToSheetOptions(items) {
  476 + const list = Array.isArray(items) ? items : []
  477 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  478 + },
  479 + labelsOfOptions(options, csv) {
  480 + const v = csv == null ? '' : String(csv)
  481 + if (!v) return ''
  482 + const parts = v.split(',').filter(Boolean)
  483 + if (!parts.length) return ''
  484 + const labels = []
  485 + ;(options || []).forEach(opt => {
  486 + const ov = opt && opt.value != null ? String(opt.value) : ''
  487 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  488 + })
  489 + return labels.filter(Boolean).join(',') || ''
  490 + },
  491 + displayLabel(field) {
  492 + const m = this.form || {}
  493 + const map = {
  494 + companyNatureName: '请选择公司性质',
  495 + purchaseSource: '请选择',
  496 + operationMode: '请选择',
  497 + isNewDevelopment: '请选择',
  498 + hasPreferentialPolicy: '请选择',
  499 + investInFutures: '请选择',
  500 + hasPenaltyRecord: '请选择',
  501 + businessScopeMatch: '请选择',
  502 + hasFailedPlanRecord: '请选择',
  503 + hasPlanPerformanceIssue: '请选择',
  504 + invoiceNameMatch: '请选择',
  505 + outboundProcessStandard: '请选择'
  506 + }
  507 + if (field === 'companyNatureName') {
  508 + const val = m[field]
  509 + return val ? String(val) : map[field]
  510 + }
  511 + if (field === 'purchaseSource') {
  512 + const v = m.purchaseSource
  513 + return v ? getDicName('PURCHASE_SOURCE', String(v), this.dicOptions.PURCHASE_SOURCE) : map[field]
  514 + }
  515 + if (field === 'operationMode') {
  516 + const v = m.operationMode
  517 + return v ? getDicName('OPERATION_METHOD', String(v), this.dicOptions.OPERATION_METHOD) : map[field]
  518 + }
  519 + if (field === 'isNewDevelopment') {
  520 + const v = m.isNewDevelopment
  521 + return v ? getDicName('DEVELOP_NEW', String(v), this.dicOptions.DEVELOP_NEW) : map[field]
  522 + }
  523 + const v = m[field]
  524 + if (v === true) return '是'
  525 + if (v === false) return '否'
  526 + return map[field] || '请选择'
  527 + },
  528 + openSheet(field) {
  529 + const map = {
  530 + purchaseSource: { title: '收购来源', options: this.purchaseSourceOptions },
  531 + operationMode: { title: '操作方式', options: this.operationMethodOptions },
  532 + isNewDevelopment: { title: '是否新开发', options: this.developNewOptions },
  533 + hasPreferentialPolicy: { title: '是否享有优惠政策', options: this.yesNoOptions },
  534 + investInFutures: { title: '是否投资期货', options: this.yesNoOptions },
  535 + hasPenaltyRecord: { title: '是否有被处罚记录', options: this.yesNoOptions },
  536 + businessScopeMatch: { title: '实际经营范围与法定经营范围是否相符', options: this.yesNoOptions },
  537 + hasFailedPlanRecord: { title: '是否有计划落空的不良记录', options: this.yesNoOptions },
  538 + hasPlanPerformanceIssue: { title: '是否有计划履行不到位现象', options: this.yesNoOptions },
  539 + invoiceNameMatch: { title: '开票品名与出库单品名是否一致', options: this.yesNoOptions },
  540 + outboundProcessStandard: { title: '出库流程是否规范', options: this.yesNoOptions }
  541 + }
  542 + const cfg = map[field]
  543 + if (!cfg) return
  544 + const current = this.form[field]
  545 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  546 + this.sheet = {
  547 + ...this.sheet,
  548 + visible: true,
  549 + title: cfg.title,
  550 + options: cfg.options || [],
  551 + field,
  552 + value: match ? match.value : current
  553 + }
  554 + },
  555 + openMultiSheet(field) {
  556 + if (field !== 'companyNature') return
  557 + this.multiSheet = {
  558 + ...this.multiSheet,
  559 + visible: true,
  560 + title: '公司性质',
  561 + options: this.companyNatureOptions || [],
  562 + field,
  563 + value: this.form.companyNature || ''
  564 + }
  565 + },
  566 + onSheetConfirm({ value, label }) {
  567 + const field = this.sheet.field
  568 + if (!field) return
  569 + this.form[field] = value
  570 + this.sheet.visible = false
  571 + },
  572 + onMultiSheetConfirm({ value, label }) {
  573 + const field = this.multiSheet.field
  574 + if (field === 'companyNature') {
  575 + const normalized = this.normalizeCompanyNature(value)
  576 + this.form.companyNature = normalized.value
  577 + this.form.companyNatureName = normalized.label
  578 + if (!this.showCompanyNatureOther) this.form.companyNatureOther = ''
  579 + }
  580 + this.multiSheet.visible = false
  581 + },
  582 + normalizeCompanyNature(valueStr) {
  583 + const selected = (valueStr ? String(valueStr).split(',').filter(Boolean) : [])
  584 + const finalSelected = selected.slice(0)
  585 + const orderedValues = []
  586 + const orderedLabels = []
  587 + ;(this.companyNatureOptions || []).forEach(opt => {
  588 + const v = opt && opt.value != null ? String(opt.value) : ''
  589 + if (v && finalSelected.includes(v)) {
  590 + orderedValues.push(v)
  591 + orderedLabels.push(opt.label != null ? String(opt.label) : '')
  592 + }
  593 + })
  594 + return { value: orderedValues.join(','), label: orderedLabels.join(',') }
  595 + },
  596 + removeAttachment(idx) {
  597 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  598 + list.splice(idx, 1)
  599 + this.attachmentFiles = list
  600 + },
  601 + onAddAttachment(val) {
  602 + const payload = val || { id: '', name: '' }
  603 + if (!payload.id) return
  604 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  605 + list.push(payload)
  606 + this.attachmentFiles = list
  607 + this.newAttachment = { id: '', name: '' }
  608 + },
  609 + onAttachmentInput(idx, val) {
  610 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  611 + list[idx] = val || { id: '', name: '' }
  612 + this.attachmentFiles = list
  613 + },
  614 + validate() {
  615 + const requiredTextFields = [
  616 + { key: 'unitName', label: '单位名称' },
  617 + { key: 'customerShortName', label: '客户简称' },
  618 + { key: 'companyNature', label: '公司性质' },
  619 + { key: 'bankName', label: '开户行' },
  620 + { key: 'bankAccount', label: '账号' },
  621 + { key: 'legalRepresentative', label: '法人代表' },
  622 + { key: 'companyEstablishedTime', label: '公司成立时间' },
  623 + { key: 'address', label: '地址' },
  624 + { key: 'businessPrincipal', label: '业务负责人' },
  625 + { key: 'businessPrincipalPosition', label: '职务' },
  626 + { key: 'businessPrincipalPhone', label: '电话' },
  627 + { key: 'legalBusinessRelation', label: '法人与业务负责人关系' },
  628 + { key: 'factoryOfficeProperty', label: '生产厂房及办公楼产权' },
  629 + { key: 'factoryOfficeArea', label: '生产厂房及办公楼面积' },
  630 + { key: 'warehouseYardProperty', label: '仓库或货场产权' },
  631 + { key: 'warehouseYardArea', label: '仓库或货场产权面积' },
  632 + { key: 'mainEquipment', label: '主要生产设备' },
  633 + { key: 'normalInventory', label: '正常库存量' },
  634 + { key: 'mainVarieties', label: '主要品种' },
  635 + { key: 'monthlyPurchaseVolume', label: '月度收购量' },
  636 + { key: 'purchaseSource', label: '收购来源' },
  637 + { key: 'stockInProductName', label: '入库品名' },
  638 + { key: 'productName', label: '产品名称' },
  639 + { key: 'capacity', label: '产能' },
  640 + { key: 'salesChannel', label: '销售渠道' },
  641 + { key: 'firstCooperationYear', label: '首次合作年份' },
  642 + { key: 'isNewDevelopment', label: '是否新开发' },
  643 + { key: 'operationMode', label: '操作方式' },
  644 + { key: 'accountingProcess', label: '进销账务如何处理' },
  645 + { key: 'transportMode', label: '运输方式' },
  646 + { key: 'commonMaterialIssue', label: '常见料质问题' },
  647 + { key: 'otherIssue', label: '合作中的其它问题' },
  648 + { key: 'purchaseDepartment', label: '采购处' },
  649 + { key: 'reviewValidUntil', label: '评审有效期' },
  650 + { key: 'investigatorId', label: '资信调查人ID' }
  651 + ]
  652 + for (let i = 0; i < requiredTextFields.length; i++) {
  653 + const f = requiredTextFields[i]
  654 + const v = this.form && this.form[f.key]
  655 + if (v == null || String(v).trim() === '') {
  656 + uni.showToast({ title: `${f.label}必填`, icon: 'none' })
  657 + return false
  658 + }
  659 + }
  660 +
  661 + const registeredCapital = Number(this.form.registeredCapital)
  662 + if (!Number.isFinite(registeredCapital) || registeredCapital < 0) {
  663 + uni.showToast({ title: '注册资金请填写数字', icon: 'none' })
  664 + return false
  665 + }
  666 +
  667 + const requiredBoolFields = [
  668 + { key: 'hasPreferentialPolicy', label: '是否享有优惠政策' },
  669 + { key: 'investInFutures', label: '是否投资期货' },
  670 + { key: 'hasPenaltyRecord', label: '是否有被处罚记录' },
  671 + { key: 'businessScopeMatch', label: '经营范围是否相符' },
  672 + { key: 'hasFailedPlanRecord', label: '计划落空不良记录' },
  673 + { key: 'hasPlanPerformanceIssue', label: '计划履行不到位现象' },
  674 + { key: 'invoiceNameMatch', label: '开票品名是否一致' },
  675 + { key: 'outboundProcessStandard', label: '出库流程是否规范' }
  676 + ]
  677 + for (let i = 0; i < requiredBoolFields.length; i++) {
  678 + const f = requiredBoolFields[i]
  679 + const v = this.form && this.form[f.key]
  680 + if (!(v === true || v === false)) {
  681 + uni.showToast({ title: `请选择${f.label}`, icon: 'none' })
  682 + return false
  683 + }
  684 + }
  685 +
  686 + const files = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.filter(it => it && it.id) : []
  687 + if (!files.length) {
  688 + uni.showToast({ title: '请上传附件', icon: 'none' })
  689 + return false
  690 + }
  691 +
  692 + const phone = String(this.form.businessPrincipalPhone || '').trim()
  693 + if (phone && !/^1\d{10}$/.test(phone)) {
  694 + uni.showToast({ title: '电话请输入11位手机号', icon: 'none' })
  695 + return false
  696 + }
  697 + const year = String(this.form.firstCooperationYear || '').trim()
  698 + if (year && !/^\d{4}$/.test(year)) {
  699 + uni.showToast({ title: '首次合作年份请填写4位年份', icon: 'none' })
  700 + return false
  701 + }
  702 + return true
  703 + },
  704 + buildPayload() {
  705 + const payload = { ...this.form }
  706 + if (!this.showCompanyNatureOther) payload.companyNatureOther = ''
  707 + delete payload.companyNatureName
  708 + delete payload.investigatorName
  709 + delete payload.purchaseDepartmentName
  710 + payload.registeredCapital = Number(payload.registeredCapital)
  711 + const files = (Array.isArray(this.attachmentFiles) ? this.attachmentFiles : []).filter(it => it && it.id)
  712 + payload.attachmentFileIds = files.map(it => String(it.id || '')).filter(Boolean).join(',')
  713 + payload.attachmentFileNames = files.map(it => String(it.name || '')).filter(Boolean).join(',')
  714 + return payload
  715 + },
  716 + async onSubmit() {
  717 + if (this.submitting) return
  718 + if (!this.validate()) return
  719 + this.submitting = true
  720 + const payload = this.buildPayload()
  721 + try {
  722 + await domesticCustomerCreditSaveApi(payload)
  723 + uni.showToast({ title: '提交成功', icon: 'success' })
  724 + try { uni.setStorageSync('DOMESTIC_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  725 + setTimeout(() => { uni.navigateBack() }, 300)
  726 + } catch (e) {
  727 + uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
  728 + } finally {
  729 + this.submitting = false
  730 + }
  731 + },
  732 + }
  733 +}
  734 +</script>
  735 +
  736 +<style lang="scss" scoped>
  737 +.page {
  738 + display: flex;
  739 + flex-direction: column;
  740 + height: 100%;
  741 +}
  742 +
  743 +.scroll {
  744 + flex: 1;
  745 + padding: 12rpx 0 160rpx;
  746 +}
  747 +
  748 +.footer {
  749 + position: fixed;
  750 + left: 0;
  751 + right: 0;
  752 + bottom: 0;
  753 + padding: 32rpx;
  754 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  755 + background: #fff;
  756 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  757 + z-index: 10;
  758 +
  759 + .btn {
  760 + height: 80rpx;
  761 + line-height: 80rpx;
  762 + border-radius: 12rpx;
  763 + font-size: 32rpx;
  764 + }
  765 +
  766 + .submit {
  767 + background: $theme-primary;
  768 + color: #fff;
  769 + }
  770 +}
  771 +
  772 +.title-header {
  773 + display: flex;
  774 + align-items: center;
  775 + padding: 24rpx 32rpx 12rpx;
  776 + background-color: #ffffff;
  777 + .title-header_icon {
  778 + width: 36rpx;
  779 + height: 36rpx;
  780 + margin-right: 12rpx;
  781 + }
  782 +
  783 + span {
  784 + font-size: 34rpx;
  785 + font-weight: 600;
  786 + color: rgba(0, 0, 0, 0.9);
  787 + }
  788 +}
  789 +
  790 +.mgb10 {
  791 + margin-bottom: 20rpx;
  792 +}
  793 +
  794 +.amount-row {
  795 + display: flex;
  796 + align-items: center;
  797 + gap: 12rpx;
  798 +
  799 + .unit, .prefix, .suffix {
  800 + font-size: 28rpx;
  801 + color: rgba(0, 0, 0, 0.6);
  802 + white-space: nowrap;
  803 + }
  804 +}
  805 +
  806 +.attach-box {
  807 + display: flex;
  808 + flex-direction: column;
  809 + align-items: flex-end;
  810 + gap: 16rpx;
  811 + width: 100%;
  812 +}
  813 +
  814 +.attach-row {
  815 + width: 100%;
  816 + display: flex;
  817 + justify-content: flex-end;
  818 + align-items: center;
  819 + gap: 20rpx;
  820 +}
  821 +
  822 +.attach-del {
  823 + font-size: 28rpx;
  824 + color: #D54941;
  825 +}
  826 +
  827 +::v-deep .uni-list {
  828 + .uni-easyinput {
  829 + display: flex;
  830 +
  831 + .uni-input-input {
  832 + color: rgba(0, 0, 0, 0.9);
  833 + }
  834 + }
  835 +
  836 + .uni-input-placeholder {
  837 + z-index: 1;
  838 + }
  839 +
  840 + .uni-input-input {
  841 + background-color: #ffffff;
  842 + }
  843 +
  844 + background: transparent;
  845 +
  846 + &-item {
  847 + &__extra-text {
  848 + font-size: 32rpx;
  849 + }
  850 +
  851 + &__content-title {
  852 + font-size: 32rpx;
  853 + color: rgba(0, 0, 0, 0.9);
  854 + }
  855 +
  856 + &__container {
  857 + padding: 32rpx;
  858 +
  859 + .uni-easyinput {
  860 + &__placeholder-class {
  861 + font-size: 32rpx;
  862 + color: rgba(0, 0, 0, 0.4);
  863 + }
  864 +
  865 + &__content {
  866 + border: none;
  867 + background-color: #ffffff !important;
  868 +
  869 + &-input {
  870 + padding-left: 0 !important;
  871 + height: 48rpx;
  872 + line-height: 48rpx;
  873 + font-size: 32rpx;
  874 + }
  875 +
  876 + .content-clear-icon {
  877 + font-size: 44rpx !important;
  878 + }
  879 + }
  880 + }
  881 +
  882 + .item-title,
  883 + .uni-list-item__content {
  884 + flex: none;
  885 + min-height: 48rpx;
  886 + line-height: 48rpx;
  887 + font-size: 32rpx;
  888 + position: relative;
  889 + width: 210rpx;
  890 + margin-right: 32rpx;
  891 + color: rgba(0, 0, 0, 0.9);
  892 +
  893 + .required {
  894 + color: red;
  895 + position: absolute;
  896 + top: 50%;
  897 + transform: translateY(-50%);
  898 + left: -16rpx;
  899 + }
  900 + }
  901 + }
  902 +
  903 + &.select-item {
  904 + &.is-empty {
  905 + .uni-list-item__extra-text {
  906 + color: rgba(0, 0, 0, 0.4) !important;
  907 + }
  908 + }
  909 +
  910 + &.is-filled {
  911 + .uni-list-item__extra-text {
  912 + color: rgba(0, 0, 0, 0.9) !important;
  913 + }
  914 + }
  915 + }
  916 +
  917 + &.mgb10 {
  918 + margin-bottom: 20rpx;
  919 + }
  920 + }
  921 +}
  922 +</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.unitName) }}</text>
  7 + <view class="row"><text class="label">客户简称</text><text class="value">{{ safeText(form.customerShortName) }}</text></view>
  8 + <view class="row"><text class="label">公司性质</text><text class="value">{{ safeText(companyNatureName) }}</text></view>
  9 + <view v-if="showCompanyNatureOther" class="row"><text class="label">其他</text><text class="value">{{ safeText(form.companyNatureOther) }}</text></view>
  10 + <view class="row"><text class="label">开户行</text><text class="value">{{ safeText(form.bankName) }}</text></view>
  11 + <view class="row"><text class="label">账号</text><text class="value">{{ safeText(form.bankAccount) }}</text></view>
  12 + <view class="row"><text class="label">注册资金(万元)</text><text class="value">{{ safeText(form.registeredCapital) }}</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.companyEstablishedTime) }}</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.businessPrincipal) }}</text></view>
  17 + <view class="row"><text class="label">职务</text><text class="value">{{ safeText(form.businessPrincipalPosition) }}</text></view>
  18 + <view class="row"><text class="label">电话</text><text class="value">{{ safeText(form.businessPrincipalPhone) }}</text></view>
  19 + <view class="row"><text class="label">法人与业务负责人关系</text><text class="value">{{ safeText(form.legalBusinessRelation) }}</text></view>
  20 + </view>
  21 +
  22 + <view class="title-header">
  23 + <image class="title-header_icon" src="/static/images/title.png" />
  24 + <span>资产状况</span>
  25 + </view>
  26 + <view class="section">
  27 + <view class="row"><text class="label">生产厂房及办公楼产权</text><text class="value">{{ safeText(form.factoryOfficeProperty) }}</text></view>
  28 + <view class="row"><text class="label">生产厂房及办公楼面积</text><text class="value">{{ safeText(form.factoryOfficeArea) }}</text></view>
  29 + <view class="row"><text class="label">仓库或货场产权</text><text class="value">{{ safeText(form.warehouseYardProperty) }}</text></view>
  30 + <view class="row"><text class="label">仓库或货场产权面积</text><text class="value">{{ safeText(form.warehouseYardArea) }}</text></view>
  31 + <view class="row"><text class="label">主要生产设备</text><text class="value pre">{{ safeText(form.mainEquipment) }}</text></view>
  32 + <view class="row"><text class="label">正常库存量</text><text class="value">{{ safeText(form.normalInventory) }}</text></view>
  33 + </view>
  34 +
  35 + <view class="title-header">
  36 + <image class="title-header_icon" src="/static/images/title.png" />
  37 + <span>生产经营环节风险调查</span>
  38 + </view>
  39 + <view class="section">
  40 + <view class="row"><text class="label">主要品种</text><text class="value">{{ safeText(form.mainVarieties) }}</text></view>
  41 + <view class="row"><text class="label">月度收购量</text><text class="value">{{ safeText(form.monthlyPurchaseVolume) }}</text></view>
  42 + <view class="row"><text class="label">收购来源</text><text class="value">{{ safeText(purchaseSourceName) }}</text></view>
  43 + <view class="row"><text class="label">入库品名</text><text class="value">{{ safeText(form.stockInProductName) }}</text></view>
  44 + <view class="row"><text class="label">产品名称</text><text class="value">{{ safeText(form.productName) }}</text></view>
  45 + <view class="row"><text class="label">产能</text><text class="value">{{ safeText(form.capacity) }}</text></view>
  46 + <view class="row"><text class="label">销售渠道</text><text class="value">{{ safeText(form.salesChannel) }}</text></view>
  47 + <view class="row"><text class="label">操作方式</text><text class="value">{{ safeText(operationModeName) }}</text></view>
  48 + <view class="row"><text class="label">是否享有优惠政策</text><text class="value">{{ boolText(form.hasPreferentialPolicy) }}</text></view>
  49 + <view class="row"><text class="label">是否投资期货</text><text class="value">{{ boolText(form.investInFutures) }}</text></view>
  50 + <view class="row"><text class="label">是否有被处罚记录</text><text class="value">{{ boolText(form.hasPenaltyRecord) }}</text></view>
  51 + <view class="row"><text class="label">经营范围是否相符</text><text class="value">{{ boolText(form.businessScopeMatch) }}</text></view>
  52 + <view class="row"><text class="label">常见料质问题</text><text class="value pre">{{ safeText(form.commonMaterialIssue) }}</text></view>
  53 + <view class="row"><text class="label">合作中的其它问题</text><text class="value pre">{{ safeText(form.otherIssue) }}</text></view>
  54 + </view>
  55 +
  56 + <view class="title-header">
  57 + <image class="title-header_icon" src="/static/images/title.png" />
  58 + <span>与我司的合作状况</span>
  59 + </view>
  60 + <view class="section">
  61 + <view class="row"><text class="label">首次合作年份</text><text class="value">{{ safeText(form.firstCooperationYear) }}</text></view>
  62 + <view class="row"><text class="label">是否新开发</text><text class="value">{{ safeText(isNewDevelopmentName) }}</text></view>
  63 + <view class="row"><text class="label">计划落空不良记录</text><text class="value">{{ boolText(form.hasFailedPlanRecord) }}</text></view>
  64 + <view class="row"><text class="label">履行不到位现象</text><text class="value">{{ boolText(form.hasPlanPerformanceIssue) }}</text></view>
  65 + <view class="row"><text class="label">进销账务如何处理</text><text class="value pre">{{ safeText(form.accountingProcess) }}</text></view>
  66 + <view class="row"><text class="label">开票品名是否一致</text><text class="value">{{ boolText(form.invoiceNameMatch) }}</text></view>
  67 + <view class="row"><text class="label">出库流程是否规范</text><text class="value">{{ boolText(form.outboundProcessStandard) }}</text></view>
  68 + <view class="row"><text class="label">运输方式</text><text class="value">{{ safeText(form.transportMode) }}</text></view>
  69 + </view>
  70 +
  71 + <view class="title-header">
  72 + <image class="title-header_icon" src="/static/images/title.png" />
  73 + <span>其他</span>
  74 + </view>
  75 + <view class="section">
  76 + <view class="row"><text class="label">资信调查人</text><text class="value">{{ safeText(form.investigatorName) }}</text></view>
  77 + <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(purchaseDepartmentName) }}</text></view>
  78 + <view class="row"><text class="label">评审有效期</text><text class="value">{{ safeText(form.reviewValidUntil) }}</text></view>
  79 + <view class="row">
  80 + <text class="label">附件</text>
  81 + <view class="value">
  82 + <view v-if="!attachments.length" class="value">-</view>
  83 + <view v-for="item in attachments" :key="item.id || item.name" class="file-item" @click="onDownload(item)">
  84 + <text class="value act">{{ item.name }}</text>
  85 + </view>
  86 + </view>
  87 + </view>
  88 + </view>
  89 + </view>
  90 + </scroll-view>
  91 + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" />
  92 + </view>
  93 +</template>
  94 +
  95 +<script>
  96 +import { downloadFile } from '@/utils/downloadFile.js'
  97 +import DetailButtons from '@/components/detail-buttons/index.vue'
  98 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  99 +import { domesticCustomerCreditCancelApi, domesticCustomerCreditGetApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  100 +import { getPurchaseDeptApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  101 +
  102 +export default {
  103 + name: 'DomesticTradeDetail',
  104 + components: {
  105 + DetailButtons
  106 + },
  107 + data() {
  108 + return {
  109 + id: '',
  110 + loading: false,
  111 + form: {},
  112 + dicOptions: {
  113 + COMPANY_NATURE: [],
  114 + DEVELOP_NEW: [],
  115 + OPERATION_METHOD: [],
  116 + PURCHASE_SOURCE: []
  117 + },
  118 + purchaseDept: null,
  119 + buttons: [{
  120 + text: '审核详情',
  121 + visible: true,
  122 + variant: 'outline',
  123 + event: 'auditDetail',
  124 + },{
  125 + text: '审核',
  126 + visible: true,
  127 + variant: 'primary',
  128 + event: 'audit',
  129 + },{
  130 + text: '编辑',
  131 + visible: true,
  132 + variant: 'outline',
  133 + event: 'edit',
  134 + },{
  135 + text: '取消',
  136 + visible: true,
  137 + variant: 'outline',
  138 + event: 'cancel',
  139 + }]
  140 + }
  141 + },
  142 + computed: {
  143 + displayButtons() {
  144 + const s = this.form && this.form.status || false
  145 + return [
  146 + { ...this.buttons[0], visible: s && this.$auth.hasPermi('procure-manage:domestic-trade:review') },
  147 + { ...this.buttons[1], visible: s === 'AUDIT' && this.$auth.hasPermi('procure-manage:domestic-trade:approve') },
  148 + { ...this.buttons[2], visible: this.$auth.hasPermi('procure-manage:domestic-trade:modify') },
  149 + { ...this.buttons[3], visible: this.$auth.hasPermi('procure-manage:domestic-trade:cancel') },
  150 + ]
  151 + },
  152 + companyNatureOptions() {
  153 + return this.dicToSheetOptions(this.dicOptions.COMPANY_NATURE)
  154 + },
  155 + attachments() {
  156 + const f = this.form || {}
  157 + const ids = f.attachmentFileIds != null ? String(f.attachmentFileIds) : ''
  158 + const names = f.attachmentFileNames != null ? String(f.attachmentFileNames) : ''
  159 + const idArr = ids ? ids.split(',').map(s => s.trim()).filter(Boolean) : []
  160 + const nameArr = names ? names.split(',') : []
  161 + if (idArr.length) {
  162 + return idArr.map((id, i) => ({ id, name: (nameArr[i] != null ? String(nameArr[i]) : '') }))
  163 + }
  164 + const legacy = Array.isArray(f.attachments) ? f.attachments : []
  165 + return legacy.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  166 + },
  167 + showCompanyNatureOther() {
  168 + const v = String((this.form && this.form.companyNature) || '')
  169 + return v.split(',').includes('OTHER')
  170 + },
  171 + companyNatureName() {
  172 + return this.safeText(this.form.companyNatureName) || this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  173 + },
  174 + purchaseSourceName() {
  175 + const v = this.form && this.form.purchaseSource != null ? String(this.form.purchaseSource) : ''
  176 + return v ? getDicName('PURCHASE_SOURCE', v, this.dicOptions.PURCHASE_SOURCE) : '-'
  177 + },
  178 + operationModeName() {
  179 + const v = this.form && this.form.operationMode != null ? String(this.form.operationMode) : ''
  180 + return v ? getDicName('OPERATION_METHOD', v, this.dicOptions.OPERATION_METHOD) : '-'
  181 + },
  182 + isNewDevelopmentName() {
  183 + const v = this.form && this.form.isNewDevelopment != null ? String(this.form.isNewDevelopment) : ''
  184 + return v ? getDicName('DEVELOP_NEW', v, this.dicOptions.DEVELOP_NEW) : '-'
  185 + },
  186 + purchaseDepartmentName() {
  187 + if (this.purchaseDept && this.purchaseDept.name != null) return String(this.purchaseDept.name)
  188 + const v = this.form && this.form.purchaseDepartmentName != null ? String(this.form.purchaseDepartmentName) : ''
  189 + return v || '-'
  190 + }
  191 + },
  192 + created() {
  193 + this.loadDicData()
  194 + this.loadPurchaseDeptOptions()
  195 + },
  196 + onShow() {
  197 + const options = (this.$route && this.$route.query) ? this.$route.query : {}
  198 + const id = options && options.id ? String(options.id) : ''
  199 + this.id = id
  200 + this.loadDetail()
  201 + },
  202 + methods: {
  203 + async loadDicData() {
  204 + try {
  205 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  206 + this.dicOptions = {
  207 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  208 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  209 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  210 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  211 + }
  212 + } catch (e) {
  213 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  214 + }
  215 + },
  216 + async loadPurchaseDeptOptions() {
  217 + try {
  218 + const res = await getPurchaseDeptApi()
  219 + const data = (res && res.data) ? res.data : {}
  220 + this.purchaseDept = (data && typeof data === 'object') ? data : null
  221 + } catch (e) {
  222 + this.purchaseDept = null
  223 + }
  224 + },
  225 + dicToSheetOptions(items) {
  226 + const list = Array.isArray(items) ? items : []
  227 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  228 + },
  229 + handleButtonClick(btn) {
  230 + if (!btn || btn.disabled) return
  231 + if (typeof btn.onClick === 'function') return btn.onClick(this.form, btn.params)
  232 + const e = btn.event || ''
  233 + if (e === 'edit') return this.onEdit(btn && btn.params)
  234 + if (e === 'audit') return this.onAudit(btn && btn.params)
  235 + if (e === 'auditDetail') return this.onAuditDetail(btn && btn.params)
  236 + if (e === 'cancel') return this.onCancel(btn && btn.params)
  237 + },
  238 + onEdit(params) {
  239 + uni.navigateTo({ url: '/pages/domestic_trade/modify?id=' + this.id })
  240 + },
  241 + onAudit(params) {
  242 + const id = this.id || (this.form && this.form.id) || ''
  243 + if (!id) return
  244 + const CACHE_KEY = 'sourceBusinessId'
  245 + const TYPE = 'contractType'
  246 + uni.setStorageSync(TYPE, 'CUSTOMER_CREDIT_IN')
  247 + uni.setStorageSync(CACHE_KEY, id)
  248 + uni.navigateTo({ url: '/pages/flow/audit' })
  249 + },
  250 + onAuditDetail(params) {
  251 + const id = this.id || (this.form && this.form.id) || ''
  252 + if (!id) return
  253 + const CACHE_KEY = 'sourceBusinessId'
  254 + const TYPE = 'contractType'
  255 + uni.setStorageSync(TYPE, 'CUSTOMER_CREDIT_IN')
  256 + uni.setStorageSync(CACHE_KEY, id)
  257 + uni.navigateTo({ url: '/pages/flow/audit_detail' })
  258 + },
  259 + onCancel(params) {
  260 + const id = this.id || (this.form && this.form.id) || ''
  261 + if (!id) return
  262 + uni.showModal({
  263 + title: '系统提示',
  264 + content: '是否确定取消该流程?',
  265 + confirmText: '确定',
  266 + cancelText: '取消',
  267 + success: (res) => {
  268 + if (res && res.confirm) {
  269 + domesticCustomerCreditCancelApi(id).then(() => {
  270 + uni.showToast({ title: '已取消', icon: 'none' })
  271 + try { uni.setStorageSync('DOMESTIC_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  272 + setTimeout(() => { uni.redirectTo({ url: '/pages/domestic_trade/index' }) }, 300)
  273 + }).catch((e) => {
  274 + uni.showToast({ title: (e && e.msg) || '取消失败', icon: 'none' })
  275 + })
  276 + }
  277 + }
  278 + })
  279 + },
  280 + boolText(v) {
  281 + if (v === true) return '是'
  282 + if (v === false) return '否'
  283 + return '-'
  284 + },
  285 + safeText(v) {
  286 + const s = v == null ? '' : String(v)
  287 + return s.trim() ? s : ''
  288 + },
  289 + labelsOf(options, csv) {
  290 + const v = csv == null ? '' : String(csv)
  291 + if (!v) return '-'
  292 + const parts = v.split(',').filter(Boolean)
  293 + if (!parts.length) return '-'
  294 + const labels = []
  295 + ;(options || []).forEach(opt => {
  296 + const ov = opt && opt.value != null ? String(opt.value) : ''
  297 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  298 + })
  299 + return labels.filter(Boolean).join(',') || '-'
  300 + },
  301 + async loadDetail() {
  302 + this.loading = true
  303 + try {
  304 + const res = await domesticCustomerCreditGetApi(this.id)
  305 + const data = (res && res.data) ? res.data : {}
  306 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  307 + if (!data.investigatorName && data.investigatorId && u && String(u.id || '') === String(data.investigatorId || '')) {
  308 + data.investigatorName = u && u.name ? String(u.name) : ''
  309 + }
  310 + this.form = data
  311 + } catch (e) {
  312 + this.form = {}
  313 + uni.showToast({ title: '详情加载失败', icon: 'none' })
  314 + } finally {
  315 + this.loading = false
  316 + }
  317 + },
  318 + onDownload(item) {
  319 + if (!item || !item.id) return
  320 + downloadFile(item.id, item.name || 'download')
  321 + }
  322 + }
  323 +}
  324 +</script>
  325 +
  326 +<style lang="scss" scoped>
  327 +.page {
  328 + display: flex;
  329 + flex-direction: column;
  330 + height: 100%;
  331 +}
  332 +
  333 +.scroll {
  334 + flex: 1;
  335 + padding: 8rpx 0 144rpx;
  336 +}
  337 +
  338 +.detail-page {
  339 + background: #f3f3f3;
  340 +}
  341 +
  342 +.title-header {
  343 + display: flex;
  344 + align-items: center;
  345 + padding: 24rpx 32rpx 12rpx;
  346 +
  347 + .title-header_icon {
  348 + width: 36rpx;
  349 + height: 36rpx;
  350 + margin-right: 12rpx;
  351 + }
  352 +
  353 + span {
  354 + font-size: 34rpx;
  355 + font-weight: 600;
  356 + color: rgba(0, 0, 0, 0.9);
  357 + }
  358 +}
  359 +
  360 +.section {
  361 + padding: 32rpx;
  362 + background: #fff;
  363 + margin-bottom: 20rpx;
  364 +}
  365 +
  366 +.row {
  367 + display: flex;
  368 + margin-bottom: 28rpx;
  369 +
  370 + &:last-child {
  371 + margin-bottom: 0;
  372 + }
  373 +
  374 + &.company {
  375 + font-size: 36rpx;
  376 + font-weight: 600;
  377 + color: rgba(0, 0, 0, 0.9);
  378 + padding-top: 8rpx;
  379 + line-height: 50rpx;
  380 + }
  381 +
  382 + .label {
  383 + max-width: 420rpx;
  384 + margin-right: 20rpx;
  385 + line-height: 32rpx;
  386 + font-size: 28rpx;
  387 + color: rgba(0, 0, 0, 0.6);
  388 + }
  389 +
  390 + .value {
  391 + flex: 1;
  392 + line-height: 32rpx;
  393 + font-size: 28rpx;
  394 + color: rgba(0, 0, 0, 0.9);
  395 + text-align: right;
  396 + word-break: break-all;
  397 +
  398 + &.act {
  399 + color: $theme-primary;
  400 + }
  401 +
  402 + &.pre {
  403 + white-space: pre-wrap;
  404 + }
  405 + }
  406 +}
  407 +.title-header {
  408 + background-color: #ffffff;
  409 +}
  410 +.file-item {
  411 + margin-bottom: 12rpx;
  412 +
  413 + &:last-child {
  414 + margin-bottom: 0;
  415 + }
  416 +}
  417 +</style>
  1 +<template>
  2 + <view class="detail-page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="section">
  5 + <text class="row company">{{ safeText(form.unitName) }}</text>
  6 + <view class="row"><text class="label">客户简称</text><text class="value">{{ safeText(form.customerShortName) }}</text></view>
  7 + <view class="row"><text class="label">公司性质</text><text class="value">{{ safeText(companyNatureName) }}</text></view>
  8 + <view class="row"><text class="label">开户行</text><text class="value">{{ safeText(form.bankName) }}</text></view>
  9 + <view class="row"><text class="label">账号</text><text class="value">{{ safeText(form.bankAccount) }}</text></view>
  10 + <view class="row"><text class="label">注册资金(万元)</text><text class="value">{{ safeText(form.registeredCapital) }}</text></view>
  11 + <view class="row"><text class="label">法人代表</text><text class="value">{{ safeText(form.legalRepresentative) }}</text></view>
  12 + <view class="row"><text class="label">公司成立时间</text><text class="value">{{ safeText(form.companyEstablishedTime) }}</text></view>
  13 + <view class="row"><text class="label">地址</text><text class="value">{{ safeText(form.address) }}</text></view>
  14 + <view class="row"><text class="label">业务负责人</text><text class="value">{{ safeText(form.businessPrincipal) }}</text></view>
  15 + <view class="row"><text class="label">职务</text><text class="value">{{ safeText(form.businessPrincipalPosition) }}</text></view>
  16 + <view class="row"><text class="label">电话</text><text class="value">{{ safeText(form.businessPrincipalPhone) }}</text></view>
  17 + <view class="row"><text class="label">法人与业务负责人关系</text><text class="value">{{ safeText(form.legalBusinessRelation) }}</text></view>
  18 + </view>
  19 +
  20 + <view class="title-header">
  21 + <image class="title-header_icon" src="/static/images/title.png" />
  22 + <span>资产状况</span>
  23 + </view>
  24 + <view class="section">
  25 + <view class="row"><text class="label">生产厂房及办公楼产权</text><text class="value">{{ safeText(form.factoryOfficeProperty) }}</text></view>
  26 + <view class="row"><text class="label">生产厂房及办公楼面积</text><text class="value">{{ safeText(form.factoryOfficeArea) }}</text></view>
  27 + <view class="row"><text class="label">仓库或货场产权</text><text class="value">{{ safeText(form.warehouseYardProperty) }}</text></view>
  28 + <view class="row"><text class="label">仓库或货场产权面积</text><text class="value">{{ safeText(form.warehouseYardArea) }}</text></view>
  29 + <view class="row"><text class="label">主要生产设备</text><text class="value pre">{{ safeText(form.mainEquipment) }}</text></view>
  30 + <view class="row"><text class="label">正常库存量</text><text class="value">{{ safeText(form.normalInventory) }}</text></view>
  31 + </view>
  32 +
  33 + <view class="title-header">
  34 + <image class="title-header_icon" src="/static/images/title.png" />
  35 + <span>生产经营环节风险调查</span>
  36 + </view>
  37 + <view class="section">
  38 + <view class="row"><text class="label">主要品种</text><text class="value">{{ safeText(form.mainVarieties) }}</text></view>
  39 + <view class="row"><text class="label">月度收购量</text><text class="value">{{ safeText(form.monthlyPurchaseVolume) }}</text></view>
  40 + <view class="row"><text class="label">收购来源</text><text class="value">{{ safeText(purchaseSourceName) }}</text></view>
  41 + <view class="row"><text class="label">入库品名</text><text class="value">{{ safeText(form.stockInProductName) }}</text></view>
  42 + <view class="row"><text class="label">产品名称</text><text class="value">{{ safeText(form.productName) }}</text></view>
  43 + <view class="row"><text class="label">产能</text><text class="value">{{ safeText(form.capacity) }}</text></view>
  44 + <view class="row"><text class="label">销售渠道</text><text class="value">{{ safeText(form.salesChannel) }}</text></view>
  45 + <view class="row"><text class="label">操作方式</text><text class="value">{{ safeText(operationModeName) }}</text></view>
  46 + <view class="row"><text class="label">是否享有优惠政策</text><text class="value">{{ boolText(form.hasPreferentialPolicy) }}</text></view>
  47 + <view class="row"><text class="label">是否投资期货</text><text class="value">{{ boolText(form.investInFutures) }}</text></view>
  48 + <view class="row"><text class="label">是否有被处罚记录</text><text class="value">{{ boolText(form.hasPenaltyRecord) }}</text></view>
  49 + <view class="row"><text class="label">经营范围是否相符</text><text class="value">{{ boolText(form.businessScopeMatch) }}</text></view>
  50 + <view class="row"><text class="label">常见料质问题</text><text class="value pre">{{ safeText(form.commonMaterialIssue) }}</text></view>
  51 + <view class="row"><text class="label">合作中的其它问题</text><text class="value pre">{{ safeText(form.otherIssue) }}</text></view>
  52 + </view>
  53 +
  54 + <view class="title-header">
  55 + <image class="title-header_icon" src="/static/images/title.png" />
  56 + <span>与我司的合作状况</span>
  57 + </view>
  58 + <view class="section">
  59 + <view class="row"><text class="label">首次合作年份</text><text class="value">{{ safeText(form.firstCooperationYear) }}</text></view>
  60 + <view class="row"><text class="label">是否新开发</text><text class="value">{{ safeText(isNewDevelopmentName) }}</text></view>
  61 + <view class="row"><text class="label">计划落空不良记录</text><text class="value">{{ boolText(form.hasFailedPlanRecord) }}</text></view>
  62 + <view class="row"><text class="label">履行不到位现象</text><text class="value">{{ boolText(form.hasPlanPerformanceIssue) }}</text></view>
  63 + <view class="row"><text class="label">进销账务如何处理</text><text class="value pre">{{ safeText(form.accountingProcess) }}</text></view>
  64 + <view class="row"><text class="label">开票品名是否一致</text><text class="value">{{ boolText(form.invoiceNameMatch) }}</text></view>
  65 + <view class="row"><text class="label">出库流程是否规范</text><text class="value">{{ boolText(form.outboundProcessStandard) }}</text></view>
  66 + <view class="row"><text class="label">运输方式</text><text class="value">{{ safeText(form.transportMode) }}</text></view>
  67 + </view>
  68 +
  69 + <view class="title-header">
  70 + <image class="title-header_icon" src="/static/images/title.png" />
  71 + <span>其他</span>
  72 + </view>
  73 + <view class="section">
  74 + <view class="row"><text class="label">资信调查人</text><text class="value">{{ safeText(form.investigatorName) }}</text></view>
  75 + <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(purchaseDepartmentName) }}</text></view>
  76 + <view class="row"><text class="label">评审有效期</text><text class="value">{{ safeText(form.reviewValidUntil) }}</text></view>
  77 + <view class="row">
  78 + <text class="label">附件</text>
  79 + <view class="value">
  80 + <view v-if="!attachments.length" class="value">-</view>
  81 + <view v-for="item in attachments" :key="item.id || item.name" class="file-item" @click="onDownload(item)">
  82 + <text class="value act">{{ item.name }}</text>
  83 + </view>
  84 + </view>
  85 + </view>
  86 + </view>
  87 + </scroll-view>
  88 + </view>
  89 +</template>
  90 +
  91 +<script>
  92 +import { downloadFile } from '@/utils/downloadFile.js'
  93 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  94 +import { domesticCustomerCreditGetExamineByIdApi, getPurchaseDeptApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  95 +
  96 +export default {
  97 + name: 'DomesticCustomerCreditViewer',
  98 + props: { id: { type: [String, Number], default: '' } },
  99 + data() {
  100 + return {
  101 + form: {},
  102 + dicOptions: {
  103 + COMPANY_NATURE: [],
  104 + DEVELOP_NEW: [],
  105 + OPERATION_METHOD: [],
  106 + PURCHASE_SOURCE: []
  107 + },
  108 + purchaseDept: null
  109 + }
  110 + },
  111 + computed: {
  112 + attachments() {
  113 + const f = this.form || {}
  114 + const ids = f.attachmentFileIds != null ? String(f.attachmentFileIds) : ''
  115 + const names = f.attachmentFileNames != null ? String(f.attachmentFileNames) : ''
  116 + const idArr = ids ? ids.split(',').map(s => s.trim()).filter(Boolean) : []
  117 + const nameArr = names ? names.split(',') : []
  118 + if (idArr.length) {
  119 + return idArr.map((id, i) => ({ id, name: (nameArr[i] != null ? String(nameArr[i]) : '') }))
  120 + }
  121 + const legacy = Array.isArray(f.attachments) ? f.attachments : []
  122 + return legacy.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  123 + },
  124 + companyNatureOptions() {
  125 + return this.dicToSheetOptions(this.dicOptions.COMPANY_NATURE)
  126 + },
  127 + companyNatureName() {
  128 + return this.safeText(this.form.companyNatureName) || this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  129 + },
  130 + purchaseSourceName() {
  131 + const v = this.form && this.form.purchaseSource != null ? String(this.form.purchaseSource) : ''
  132 + return v ? getDicName('PURCHASE_SOURCE', v, this.dicOptions.PURCHASE_SOURCE) : '-'
  133 + },
  134 + operationModeName() {
  135 + const v = this.form && this.form.operationMode != null ? String(this.form.operationMode) : ''
  136 + return v ? getDicName('OPERATION_METHOD', v, this.dicOptions.OPERATION_METHOD) : '-'
  137 + },
  138 + isNewDevelopmentName() {
  139 + const v = this.form && this.form.isNewDevelopment != null ? String(this.form.isNewDevelopment) : ''
  140 + return v ? getDicName('DEVELOP_NEW', v, this.dicOptions.DEVELOP_NEW) : '-'
  141 + },
  142 + purchaseDepartmentName() {
  143 + if (this.purchaseDept && this.purchaseDept.name != null) return String(this.purchaseDept.name)
  144 + const v = this.form && this.form.purchaseDepartmentName != null ? String(this.form.purchaseDepartmentName) : ''
  145 + return v || '-'
  146 + }
  147 + },
  148 + created() {
  149 + this.loadDicData()
  150 + this.loadPurchaseDeptOptions()
  151 + },
  152 + watch: {
  153 + id: {
  154 + immediate: true,
  155 + handler(val) {
  156 + const v = (val !== undefined && val !== null) ? String(val) : ''
  157 + if (v) this.loadDetail(v)
  158 + }
  159 + }
  160 + },
  161 + methods: {
  162 + async loadDicData() {
  163 + try {
  164 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  165 + this.dicOptions = {
  166 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  167 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  168 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  169 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  170 + }
  171 + } catch (e) {
  172 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  173 + }
  174 + },
  175 + async loadPurchaseDeptOptions() {
  176 + try {
  177 + const res = await getPurchaseDeptApi()
  178 + const data = (res && res.data) ? res.data : {}
  179 + this.purchaseDept = (data && typeof data === 'object') ? data : null
  180 + } catch (e) {
  181 + this.purchaseDept = null
  182 + }
  183 + },
  184 + dicToSheetOptions(items) {
  185 + const list = Array.isArray(items) ? items : []
  186 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  187 + },
  188 + labelsOf(options, csv) {
  189 + const v = csv == null ? '' : String(csv)
  190 + if (!v) return '-'
  191 + const parts = v.split(',').filter(Boolean)
  192 + if (!parts.length) return '-'
  193 + const labels = []
  194 + ;(options || []).forEach(opt => {
  195 + const ov = opt && opt.value != null ? String(opt.value) : ''
  196 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  197 + })
  198 + return labels.filter(Boolean).join(',') || '-'
  199 + },
  200 + boolText(v) {
  201 + if (v === true) return '是'
  202 + if (v === false) return '否'
  203 + return '-'
  204 + },
  205 + safeText(v) {
  206 + const s = v == null ? '' : String(v)
  207 + return s.trim() ? s : ''
  208 + },
  209 + async loadDetail(id) {
  210 + try {
  211 + const res = await domesticCustomerCreditGetExamineByIdApi(id)
  212 + this.form = (res && res.data) ? res.data : {}
  213 + } catch (e) {
  214 + this.form = {}
  215 + }
  216 + },
  217 + onDownload(item) {
  218 + if (!item || !item.id) return
  219 + downloadFile(item.id, item.name || 'download')
  220 + }
  221 + }
  222 +}
  223 +</script>
  224 +
  225 +<style lang="scss" scoped>
  226 +.detail-page {
  227 + background: #f3f3f3;
  228 +}
  229 +
  230 +.scroll {
  231 + flex: 1;
  232 + padding: 8rpx 0 144rpx;
  233 +}
  234 +
  235 +.title-header {
  236 + display: flex;
  237 + align-items: center;
  238 + padding: 24rpx 32rpx 12rpx;
  239 + background-color: #ffffff;
  240 +
  241 + .title-header_icon {
  242 + width: 36rpx;
  243 + height: 36rpx;
  244 + margin-right: 12rpx;
  245 + }
  246 +
  247 + span {
  248 + font-size: 34rpx;
  249 + font-weight: 600;
  250 + color: rgba(0, 0, 0, 0.9);
  251 + }
  252 +}
  253 +
  254 +.section {
  255 + padding: 32rpx;
  256 + background: #fff;
  257 + margin-bottom: 20rpx;
  258 +}
  259 +
  260 +.row {
  261 + display: flex;
  262 + margin-bottom: 28rpx;
  263 +
  264 + &:last-child {
  265 + margin-bottom: 0;
  266 + }
  267 +
  268 + &.company {
  269 + font-size: 36rpx;
  270 + font-weight: 600;
  271 + color: rgba(0, 0, 0, 0.9);
  272 + padding-top: 8rpx;
  273 + line-height: 50rpx;
  274 + }
  275 +
  276 + .label {
  277 + max-width: 420rpx;
  278 + margin-right: 20rpx;
  279 + line-height: 32rpx;
  280 + font-size: 28rpx;
  281 + color: rgba(0, 0, 0, 0.6);
  282 + }
  283 +
  284 + .value {
  285 + flex: 1;
  286 + line-height: 32rpx;
  287 + font-size: 28rpx;
  288 + color: rgba(0, 0, 0, 0.9);
  289 + text-align: right;
  290 + word-break: break-all;
  291 +
  292 + &.act {
  293 + color: $theme-primary;
  294 + }
  295 +
  296 + &.pre {
  297 + white-space: pre-wrap;
  298 + }
  299 + }
  300 +}
  301 +
  302 +.file-item {
  303 + margin-bottom: 12rpx;
  304 +
  305 + &:last-child {
  306 + margin-bottom: 0;
  307 + }
  308 +}
  309 +</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.unitName || '-' }}</text>
  22 + <text :class="['status', `status_${item.status}`]">{{ getAuditStatusText(item.status) }}</text>
  23 + </view>
  24 + <view class="info-row">
  25 + <text>公司性质</text><text>{{ companyNatureText(item) }}</text>
  26 + </view>
  27 + <view class="info-row">
  28 + <text>电话</text><text>{{ item.businessPrincipalPhone || '-' }}</text>
  29 + </view>
  30 + <view class="info-row">
  31 + <text>业务负责人</text><text>{{ item.businessPrincipal || '-' }}</text>
  32 + </view>
  33 + <view class="info-row">
  34 + <text>登记日期</text><text>{{ formatDateOnly(item.createTime) }}</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.status" @change="onAuditStatusChange" :localdata="statusOptions" />
  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 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  64 +import { domesticCustomerCreditQueryApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  65 +
  66 +export default {
  67 + name: 'DomesticTradeList',
  68 + components: { CardList, FilterModal },
  69 + data() {
  70 + return {
  71 + searchKeyword: '',
  72 + searchKeywordDebounced: '',
  73 + searchDebounceTimer: null,
  74 + query: {
  75 + unitName: '',
  76 + status: '',
  77 + dateRange: []
  78 + },
  79 + extraParams: {},
  80 + currentItems: [],
  81 + filterVisible: false,
  82 + filterForm: {
  83 + status: '',
  84 + dateRange: []
  85 + },
  86 + statusOptions: [
  87 + { value: '', text: '全部' }
  88 + ],
  89 + dicOptions: {
  90 + AUDIT_STATUS: [],
  91 + COMPANY_NATURE: []
  92 + },
  93 + }
  94 + },
  95 + watch: {
  96 + searchKeywordDebounced(v) {
  97 + this.query = { ...this.query, unitName: v || '' }
  98 + }
  99 + },
  100 + created() {
  101 + this.loadDicData()
  102 + },
  103 + onShow() {
  104 + let needRefresh = ''
  105 + try { needRefresh = uni.getStorageSync('DOMESTIC_TRADE_LIST_NEED_REFRESH') } catch (e) {}
  106 + if (!needRefresh) return
  107 + try { uni.removeStorageSync('DOMESTIC_TRADE_LIST_NEED_REFRESH') } catch (e) {}
  108 + if (this.$refs && this.$refs.cardRef && this.$refs.cardRef.reload) {
  109 + this.$refs.cardRef.reload()
  110 + }
  111 + },
  112 + onReachBottom() {
  113 + if (this.$refs && this.$refs.cardRef && this.$refs.cardRef.onLoadMore) {
  114 + this.$refs.cardRef.onLoadMore()
  115 + }
  116 + },
  117 + beforeDestroy() {
  118 + if (this.searchDebounceTimer) {
  119 + clearTimeout(this.searchDebounceTimer)
  120 + this.searchDebounceTimer = null
  121 + }
  122 + },
  123 + methods: {
  124 + async loadDicData() {
  125 + try {
  126 + const results = await getDicByCodes(['AUDIT_STATUS', 'COMPANY_NATURE'])
  127 + this.dicOptions.AUDIT_STATUS = (results.AUDIT_STATUS && results.AUDIT_STATUS.data) || []
  128 + this.dicOptions.COMPANY_NATURE = (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || []
  129 + const list = Array.isArray(this.dicOptions.AUDIT_STATUS) ? this.dicOptions.AUDIT_STATUS : []
  130 + this.statusOptions = [{ value: '', text: '全部' }].concat(
  131 + list.map(it => ({ value: it && it.code != null ? String(it.code) : '', text: it && it.name != null ? String(it.name) : '' })).filter(it => it.value)
  132 + )
  133 + } catch (e) {
  134 + this.dicOptions.AUDIT_STATUS = []
  135 + this.dicOptions.COMPANY_NATURE = []
  136 + this.statusOptions = [{ value: '', text: '全部' }]
  137 + }
  138 + },
  139 + companyNatureText(item) {
  140 + const v = item && item.companyNature != null ? String(item.companyNature) : ''
  141 + if (!v) return '-'
  142 + const parts = v.split(',').map(s => s.trim()).filter(Boolean)
  143 + if (parts.length > 1) {
  144 + return parts.map(code => getDicName('COMPANY_NATURE', code, this.dicOptions.COMPANY_NATURE)).filter(Boolean).join(',')
  145 + }
  146 + return getDicName('COMPANY_NATURE', v, this.dicOptions.COMPANY_NATURE) || v
  147 + },
  148 + formatDateOnly(v) {
  149 + const s = v == null ? '' : String(v).trim()
  150 + if (!s) return '-'
  151 + if (s.length >= 10) return s.slice(0, 10)
  152 + return s
  153 + },
  154 + onAdd() {
  155 + uni.navigateTo({ url: '/pages/domestic_trade/add' })
  156 + },
  157 + onCardLoaded({ items }) {
  158 + this.currentItems = items
  159 + },
  160 + onCardError() {
  161 + uni.showToast({ title: '列表加载失败', icon: 'none' })
  162 + },
  163 + onSearchInput() {
  164 + if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer)
  165 + this.searchDebounceTimer = setTimeout(() => {
  166 + this.searchKeywordDebounced = this.searchKeyword
  167 + this.searchDebounceTimer = null
  168 + }, 1200)
  169 + },
  170 + search(e) {
  171 + const val = e && e.value != null ? e.value : this.searchKeyword
  172 + this.searchKeyword = val
  173 + this.searchKeywordDebounced = val
  174 + },
  175 + openFilter() {
  176 + this.filterForm = {
  177 + status: this.query.status || '',
  178 + dateRange: Array.isArray(this.query.dateRange) ? this.query.dateRange.slice(0) : []
  179 + }
  180 + this.filterVisible = true
  181 + },
  182 + onFilterReset(payload) {
  183 + this.filterForm = payload
  184 + },
  185 + onFilterConfirm(payload) {
  186 + this.query = {
  187 + unitName: this.query.unitName || '',
  188 + status: payload.status || '',
  189 + dateRange: Array.isArray(payload.dateRange) ? payload.dateRange : []
  190 + }
  191 + },
  192 + onAuditStatusChange(e) {
  193 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  194 + this.filterForm.status = raw
  195 + },
  196 + getAuditStatusText(status) {
  197 + const v = status == null ? '' : String(status)
  198 + if (!v) return '-'
  199 + return getDicName('AUDIT_STATUS', v, this.dicOptions.AUDIT_STATUS) || v
  200 + },
  201 + fetchList({ pageIndex, pageSize, query }) {
  202 + const q = query || {}
  203 + const range = Array.isArray(q.dateRange) ? q.dateRange : []
  204 + const params = {
  205 + pageIndex,
  206 + pageSize,
  207 + unitName: q.unitName || '',
  208 + status: q.status || '',
  209 + createDateStart: (range && range.length === 2) ? range[0] : '',
  210 + createDateEnd: (range && range.length === 2) ? range[1] : ''
  211 + }
  212 + return domesticCustomerCreditQueryApi(params).then(res => {
  213 + const _data = res && res.data ? res.data : {}
  214 + let records = _data.datas || _data.list || _data.records || []
  215 + const totalCount = _data.totalCount || _data.count || 0
  216 + const hasNext = _data.hasNext || false
  217 + records = records.map(it => ({ ...it }))
  218 + return { records, totalCount, hasNext }
  219 + }).catch(() => {
  220 + this.onCardError()
  221 + return { records: [], totalCount: 0, hasNext: false }
  222 + })
  223 + },
  224 + onCardClick(item) {
  225 + uni.navigateTo({ url: '/pages/domestic_trade/detail?id=' + item.id })
  226 + },
  227 + }
  228 +}
  229 +</script>
  230 +
  231 +<style lang="scss" scoped>
  232 +.page {
  233 + display: flex;
  234 + flex-direction: column;
  235 + height: 100vh;
  236 +}
  237 +
  238 +.dev-list-fixed {
  239 + position: fixed;
  240 + top: 96rpx;
  241 + left: 0;
  242 + right: 0;
  243 + z-index: 2;
  244 + background: #fff;
  245 +
  246 + .search-row {
  247 + display: flex;
  248 + align-items: center;
  249 + padding: 16rpx 32rpx;
  250 +
  251 + .uni-searchbar {
  252 + padding: 0;
  253 + flex: 1;
  254 + }
  255 +
  256 + .tool-icons {
  257 + display: flex;
  258 +
  259 + .tool-icon {
  260 + width: 48rpx;
  261 + height: 48rpx;
  262 + display: block;
  263 + margin-left: 32rpx;
  264 + }
  265 + }
  266 + }
  267 +}
  268 +
  269 +::v-deep .uni-searchbar__box {
  270 + height: 80rpx !important;
  271 + justify-content: start;
  272 +
  273 + .uni-searchbar__box-search-input {
  274 + font-size: 32rpx !important;
  275 + }
  276 +}
  277 +
  278 +.list-box {
  279 + flex: 1;
  280 + padding-top: 140rpx;
  281 +
  282 + .card {
  283 + position: relative;
  284 + }
  285 +
  286 + .card-header {
  287 + margin-bottom: 28rpx;
  288 + position: relative;
  289 +
  290 + .title {
  291 + font-size: 36rpx;
  292 + font-weight: 600;
  293 + line-height: 50rpx;
  294 + color: rgba(0, 0, 0, 0.9);
  295 + width: 578rpx;
  296 + }
  297 +
  298 + .status {
  299 + position: absolute;
  300 + top: -32rpx;
  301 + right: -12rpx;
  302 + height: 48rpx;
  303 + line-height: 48rpx;
  304 + font-weight: 600;
  305 + color: #fff;
  306 + font-size: 24rpx;
  307 + padding: 0 14rpx;
  308 + border-radius: 6rpx;
  309 +
  310 + &.status_AUDIT {
  311 + background: $theme-primary;
  312 + }
  313 +
  314 + &.status_PASS {
  315 + background: #2BA471;
  316 + }
  317 +
  318 + &.status_REFUSE {
  319 + background: #D54941;
  320 + }
  321 +
  322 + &.status_CANCEL {
  323 + background: #E7E7E7;
  324 + color: rgba(0, 0, 0, 0.9);
  325 + }
  326 + }
  327 + }
  328 +
  329 + .info-row {
  330 + display: flex;
  331 + align-items: center;
  332 + color: rgba(0, 0, 0, 0.6);
  333 + font-size: 28rpx;
  334 + margin-bottom: 24rpx;
  335 + height: 32rpx;
  336 +
  337 + &:last-child {
  338 + margin-bottom: 0;
  339 + }
  340 +
  341 + text {
  342 + width: 50%;
  343 +
  344 + &:last-child {
  345 + color: rgba(0, 0, 0, 0.9);
  346 + width: 50%;
  347 + }
  348 + }
  349 + }
  350 +}
  351 +
  352 +.filter-form {
  353 + .form-item {
  354 + margin-bottom: 24rpx;
  355 + }
  356 +
  357 + .label {
  358 + margin-bottom: 20rpx;
  359 + color: rgba(0, 0, 0, 0.9);
  360 + height: 44rpx;
  361 + line-height: 44rpx;
  362 + font-size: 30rpx;
  363 + }
  364 +}
  365 +</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.unitName" placeholder="请输入单位名称" :inputBorder="false" />
  13 + </template>
  14 + </uni-list-item>
  15 + <uni-list-item title="客户简称">
  16 + <template v-slot:footer>
  17 + <uni-easyinput v-model="form.customerShortName" placeholder="请输入客户简称" :inputBorder="false" />
  18 + </template>
  19 + </uni-list-item>
  20 + <uni-list-item class="select-item" :class="form.companyNatureName ? 'is-filled' : 'is-empty'" clickable
  21 + @click="openMultiSheet('companyNature')" :rightText="displayLabel('companyNatureName')" showArrow>
  22 + <template v-slot:body>
  23 + <view class="item-title"><text>公司性质</text></view>
  24 + </template>
  25 + </uni-list-item>
  26 + <uni-list-item v-if="showCompanyNatureOther" class="mgb10" title="其他">
  27 + <template v-slot:footer>
  28 + <uni-easyinput v-model="form.companyNatureOther" 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.bankName" 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.bankAccount" placeholder="请输入账号" :inputBorder="false" />
  41 + </template>
  42 + </uni-list-item>
  43 +
  44 + <uni-list-item class="amount-item">
  45 + <template v-slot:body>
  46 + <view class="item-title"><text>注册资金</text></view>
  47 + </template>
  48 + <template v-slot:footer>
  49 + <view class="amount-row">
  50 + <uni-easyinput type="digit" v-model="form.registeredCapital" placeholder="请输入" :inputBorder="false" />
  51 + <text class="unit">万元</text>
  52 + </view>
  53 + </template>
  54 + </uni-list-item>
  55 +
  56 + <uni-list-item title="法人代表">
  57 + <template v-slot:footer>
  58 + <uni-easyinput v-model="form.legalRepresentative" placeholder="请输入法人代表" :inputBorder="false" />
  59 + </template>
  60 + </uni-list-item>
  61 +
  62 + <uni-list-item title="公司成立时间">
  63 + <template v-slot:footer>
  64 + <uni-datetime-picker type="date" v-model="form.companyEstablishedTime" />
  65 + </template>
  66 + </uni-list-item>
  67 +
  68 + <uni-list-item title="地址">
  69 + <template v-slot:footer>
  70 + <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
  71 + </template>
  72 + </uni-list-item>
  73 +
  74 + <uni-list-item title="业务负责人">
  75 + <template v-slot:footer>
  76 + <uni-easyinput v-model="form.businessPrincipal" placeholder="请输入业务负责人" :inputBorder="false" />
  77 + </template>
  78 + </uni-list-item>
  79 +
  80 + <uni-list-item title="职务">
  81 + <template v-slot:footer>
  82 + <uni-easyinput v-model="form.businessPrincipalPosition" placeholder="请输入职务" :inputBorder="false" />
  83 + </template>
  84 + </uni-list-item>
  85 +
  86 + <uni-list-item title="电话">
  87 + <template v-slot:footer>
  88 + <uni-easyinput type="number" v-model="form.businessPrincipalPhone" placeholder="请输入手机号码" :inputBorder="false" />
  89 + </template>
  90 + </uni-list-item>
  91 +
  92 + <uni-list-item class="mgb10" title="法人与业务负责人关系">
  93 + <template v-slot:footer>
  94 + <uni-easyinput v-model="form.legalBusinessRelation" placeholder="请输入" :inputBorder="false" />
  95 + </template>
  96 + </uni-list-item>
  97 +
  98 + <view class="title-header">
  99 + <image class="title-header_icon" src="/static/images/title.png" />
  100 + <span>资产状况</span>
  101 + </view>
  102 +
  103 + <uni-list-item title="生产厂房及办公楼产权">
  104 + <template v-slot:footer>
  105 + <uni-easyinput v-model="form.factoryOfficeProperty" placeholder="请输入" :inputBorder="false" />
  106 + </template>
  107 + </uni-list-item>
  108 +
  109 + <uni-list-item title="生产厂房及办公楼面积">
  110 + <template v-slot:footer>
  111 + <uni-easyinput v-model="form.factoryOfficeArea" placeholder="请输入" :inputBorder="false" />
  112 + </template>
  113 + </uni-list-item>
  114 +
  115 + <uni-list-item title="仓库或货场产权">
  116 + <template v-slot:footer>
  117 + <uni-easyinput v-model="form.warehouseYardProperty" placeholder="请输入" :inputBorder="false" />
  118 + </template>
  119 + </uni-list-item>
  120 +
  121 + <uni-list-item title="仓库或货场产权面积">
  122 + <template v-slot:footer>
  123 + <uni-easyinput v-model="form.warehouseYardArea" placeholder="请输入" :inputBorder="false" />
  124 + </template>
  125 + </uni-list-item>
  126 +
  127 + <uni-list-item title="主要生产设备">
  128 + <template v-slot:footer>
  129 + <uni-easyinput type="textarea" v-model="form.mainEquipment" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  130 + </template>
  131 + </uni-list-item>
  132 +
  133 + <uni-list-item class="mgb10" title="正常库存量">
  134 + <template v-slot:footer>
  135 + <uni-easyinput v-model="form.normalInventory" placeholder="请输入" :inputBorder="false" />
  136 + </template>
  137 + </uni-list-item>
  138 +
  139 + <view class="title-header">
  140 + <image class="title-header_icon" src="/static/images/title.png" />
  141 + <span>生产经营环节风险调查</span>
  142 + </view>
  143 +
  144 + <uni-list-item title="主要品种">
  145 + <template v-slot:footer>
  146 + <uni-easyinput v-model="form.mainVarieties" placeholder="请输入" :inputBorder="false" />
  147 + </template>
  148 + </uni-list-item>
  149 +
  150 + <uni-list-item title="月度收购量">
  151 + <template v-slot:footer>
  152 + <uni-easyinput v-model="form.monthlyPurchaseVolume" placeholder="请输入" :inputBorder="false" />
  153 + </template>
  154 + </uni-list-item>
  155 +
  156 + <uni-list-item class="select-item" :class="form.purchaseSource ? 'is-filled' : 'is-empty'" clickable
  157 + @click="openSheet('purchaseSource')" :rightText="displayLabel('purchaseSource')" showArrow>
  158 + <template v-slot:body>
  159 + <view class="item-title"><text>收购来源</text></view>
  160 + </template>
  161 + </uni-list-item>
  162 +
  163 + <uni-list-item title="入库品名">
  164 + <template v-slot:footer>
  165 + <uni-easyinput v-model="form.stockInProductName" placeholder="请输入" :inputBorder="false" />
  166 + </template>
  167 + </uni-list-item>
  168 +
  169 + <uni-list-item title="产品名称">
  170 + <template v-slot:footer>
  171 + <uni-easyinput v-model="form.productName" placeholder="请输入" :inputBorder="false" />
  172 + </template>
  173 + </uni-list-item>
  174 +
  175 + <uni-list-item title="产能">
  176 + <template v-slot:footer>
  177 + <uni-easyinput v-model="form.capacity" placeholder="请输入" :inputBorder="false" />
  178 + </template>
  179 + </uni-list-item>
  180 +
  181 + <uni-list-item title="销售渠道">
  182 + <template v-slot:footer>
  183 + <uni-easyinput v-model="form.salesChannel" placeholder="请输入" :inputBorder="false" />
  184 + </template>
  185 + </uni-list-item>
  186 +
  187 + <uni-list-item class="select-item" :class="form.operationMode ? 'is-filled' : 'is-empty'" clickable
  188 + @click="openSheet('operationMode')" :rightText="displayLabel('operationMode')" showArrow>
  189 + <template v-slot:body>
  190 + <view class="item-title"><text>操作方式</text></view>
  191 + </template>
  192 + </uni-list-item>
  193 +
  194 + <uni-list-item class="select-item" :class="form.hasPreferentialPolicy === true || form.hasPreferentialPolicy === false ? 'is-filled' : 'is-empty'" clickable
  195 + @click="openSheet('hasPreferentialPolicy')" :rightText="displayLabel('hasPreferentialPolicy')" showArrow>
  196 + <template v-slot:body>
  197 + <view class="item-title"><text>是否享有优惠政策</text></view>
  198 + </template>
  199 + </uni-list-item>
  200 +
  201 + <uni-list-item class="select-item" :class="form.investInFutures === true || form.investInFutures === false ? 'is-filled' : 'is-empty'" clickable
  202 + @click="openSheet('investInFutures')" :rightText="displayLabel('investInFutures')" showArrow>
  203 + <template v-slot:body>
  204 + <view class="item-title"><text>是否投资期货</text></view>
  205 + </template>
  206 + </uni-list-item>
  207 +
  208 + <uni-list-item class="select-item" :class="form.hasPenaltyRecord === true || form.hasPenaltyRecord === false ? 'is-filled' : 'is-empty'" clickable
  209 + @click="openSheet('hasPenaltyRecord')" :rightText="displayLabel('hasPenaltyRecord')" showArrow>
  210 + <template v-slot:body>
  211 + <view class="item-title"><text>是否有被处罚记录</text></view>
  212 + </template>
  213 + </uni-list-item>
  214 +
  215 + <uni-list-item class="select-item" :class="form.businessScopeMatch === true || form.businessScopeMatch === false ? 'is-filled' : 'is-empty'" clickable
  216 + @click="openSheet('businessScopeMatch')" :rightText="displayLabel('businessScopeMatch')" showArrow>
  217 + <template v-slot:body>
  218 + <view class="item-title"><text>实际经营范围与法定经营范围是否相符</text></view>
  219 + </template>
  220 + </uni-list-item>
  221 +
  222 + <uni-list-item title="常见料质问题">
  223 + <template v-slot:footer>
  224 + <uni-easyinput type="textarea" v-model="form.commonMaterialIssue" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  225 + </template>
  226 + </uni-list-item>
  227 +
  228 + <uni-list-item class="mgb10" title="合作中的其它问题">
  229 + <template v-slot:footer>
  230 + <uni-easyinput type="textarea" v-model="form.otherIssue" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  231 + </template>
  232 + </uni-list-item>
  233 +
  234 + <view class="title-header">
  235 + <image class="title-header_icon" src="/static/images/title.png" />
  236 + <span>与我司的合作状况</span>
  237 + </view>
  238 +
  239 + <uni-list-item title="首次合作年份">
  240 + <template v-slot:footer>
  241 + <uni-easyinput type="digit" v-model="form.firstCooperationYear" placeholder="请输入4位年份" :inputBorder="false" />
  242 + </template>
  243 + </uni-list-item>
  244 +
  245 + <uni-list-item class="select-item" :class="form.isNewDevelopment ? 'is-filled' : 'is-empty'" clickable
  246 + @click="openSheet('isNewDevelopment')" :rightText="displayLabel('isNewDevelopment')" showArrow>
  247 + <template v-slot:body>
  248 + <view class="item-title"><text>是否新开发</text></view>
  249 + </template>
  250 + </uni-list-item>
  251 +
  252 + <uni-list-item class="select-item" :class="form.hasFailedPlanRecord === true || form.hasFailedPlanRecord === false ? 'is-filled' : 'is-empty'" clickable
  253 + @click="openSheet('hasFailedPlanRecord')" :rightText="displayLabel('hasFailedPlanRecord')" showArrow>
  254 + <template v-slot:body>
  255 + <view class="item-title"><text>是否有计划落空的不良记录</text></view>
  256 + </template>
  257 + </uni-list-item>
  258 + <uni-list-item class="select-item" :class="form.hasPlanPerformanceIssue === true || form.hasPlanPerformanceIssue === false ? 'is-filled' : 'is-empty'" clickable
  259 + @click="openSheet('hasPlanPerformanceIssue')" :rightText="displayLabel('hasPlanPerformanceIssue')" showArrow>
  260 + <template v-slot:body>
  261 + <view class="item-title"><text>是否有计划履行不到位现象</text></view>
  262 + </template>
  263 + </uni-list-item>
  264 +
  265 + <uni-list-item title="进销账务如何处理">
  266 + <template v-slot:footer>
  267 + <uni-easyinput type="textarea" v-model="form.accountingProcess" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  268 + </template>
  269 + </uni-list-item>
  270 +
  271 + <uni-list-item class="select-item" :class="form.invoiceNameMatch === true || form.invoiceNameMatch === false ? 'is-filled' : 'is-empty'" clickable
  272 + @click="openSheet('invoiceNameMatch')" :rightText="displayLabel('invoiceNameMatch')" showArrow>
  273 + <template v-slot:body>
  274 + <view class="item-title"><text>开票品名与出库单品名是否一致</text></view>
  275 + </template>
  276 + </uni-list-item>
  277 +
  278 + <uni-list-item class="select-item" :class="form.outboundProcessStandard === true || form.outboundProcessStandard === false ? 'is-filled' : 'is-empty'" clickable
  279 + @click="openSheet('outboundProcessStandard')" :rightText="displayLabel('outboundProcessStandard')" showArrow>
  280 + <template v-slot:body>
  281 + <view class="item-title"><text>出库流程是否规范</text></view>
  282 + </template>
  283 + </uni-list-item>
  284 +
  285 + <uni-list-item class="mgb10" title="运输方式">
  286 + <template v-slot:footer>
  287 + <uni-easyinput v-model="form.transportMode" placeholder="请输入" :inputBorder="false" />
  288 + </template>
  289 + </uni-list-item>
  290 +
  291 + <view class="title-header">
  292 + <image class="title-header_icon" src="/static/images/title.png" />
  293 + <span>其他</span>
  294 + </view>
  295 +
  296 + <uni-list-item title="资信调查人">
  297 + <template v-slot:footer>
  298 + <uni-easyinput v-model="form.investigatorName" disabled placeholder="" :inputBorder="false" />
  299 + </template>
  300 + </uni-list-item>
  301 +
  302 + <uni-list-item title="采购处">
  303 + <template v-slot:footer>
  304 + <uni-easyinput v-model="form.purchaseDepartmentName" disabled placeholder="" :inputBorder="false" />
  305 + </template>
  306 + </uni-list-item>
  307 +
  308 + <uni-list-item title="评审有效期">
  309 + <template v-slot:footer>
  310 + <uni-datetime-picker type="date" v-model="form.reviewValidUntil" />
  311 + </template>
  312 + </uni-list-item>
  313 +
  314 + <uni-list-item class="mgb10" title="附件">
  315 + <template v-slot:footer>
  316 + <view class="attach-box">
  317 + <view v-for="(f, idx) in attachmentFiles" :key="idx" class="attach-row">
  318 + <FileUpload :value="f" @input="onAttachmentInput(idx, $event)" />
  319 + <text class="attach-del" @click.stop="removeAttachment(idx)">删除</text>
  320 + </view>
  321 + <view class="attach-row">
  322 + <FileUpload :value="newAttachment" @input="onAddAttachment" />
  323 + </view>
  324 + </view>
  325 + </template>
  326 + </uni-list-item>
  327 + </uni-list>
  328 + </scroll-view>
  329 +
  330 + <view class="footer">
  331 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '保存中...' : '保存' }}</button>
  332 + </view>
  333 +
  334 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  335 + @confirm="onSheetConfirm" />
  336 + <MultiSelectSheet :visible.sync="multiSheet.visible" :title="multiSheet.title" :options="multiSheet.options"
  337 + v-model="multiSheet.value" @confirm="onMultiSheetConfirm" />
  338 + </view>
  339 +</template>
  340 +
  341 +<script>
  342 +import FileUpload from '@/components/file-upload/index.vue'
  343 +import SingleSelectSheet from '@/components/single-select/index.vue'
  344 +import MultiSelectSheet from '@/components/multi-select/index.vue'
  345 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  346 +import { domesticCustomerCreditGetApi, domesticCustomerCreditSaveApi, getPurchaseDeptApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  347 +
  348 +export default {
  349 + name: 'DomesticTradeModify',
  350 + components: { FileUpload, SingleSelectSheet, MultiSelectSheet },
  351 + data() {
  352 + return {
  353 + id: '',
  354 + submitting: false,
  355 + loading: false,
  356 + newAttachment: { id: '', name: '' },
  357 + attachmentFiles: [],
  358 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  359 + multiSheet: { visible: false, title: '', options: [], field: '', value: '' },
  360 + dicOptions: {
  361 + COMPANY_NATURE: [],
  362 + DEVELOP_NEW: [],
  363 + OPERATION_METHOD: [],
  364 + PURCHASE_SOURCE: []
  365 + },
  366 + yesNoOptions: [
  367 + { label: '是', value: true },
  368 + { label: '否', value: false }
  369 + ],
  370 + companyNatureOptions: [],
  371 + operationMethodOptions: [],
  372 + developNewOptions: [],
  373 + purchaseSourceOptions: [],
  374 + purchaseDept: null,
  375 + form: {
  376 + id: '',
  377 + unitName: '',
  378 + customerShortName: '',
  379 + companyNature: '',
  380 + companyNatureName: '',
  381 + companyNatureOther: '',
  382 + bankName: '',
  383 + bankAccount: '',
  384 + registeredCapital: '',
  385 + legalRepresentative: '',
  386 + companyEstablishedTime: '',
  387 + address: '',
  388 + businessPrincipal: '',
  389 + businessPrincipalPosition: '',
  390 + businessPrincipalPhone: '',
  391 + legalBusinessRelation: '',
  392 + factoryOfficeProperty: '',
  393 + factoryOfficeArea: '',
  394 + warehouseYardProperty: '',
  395 + warehouseYardArea: '',
  396 + mainEquipment: '',
  397 + normalInventory: '',
  398 + mainVarieties: '',
  399 + monthlyPurchaseVolume: '',
  400 + purchaseSource: '',
  401 + stockInProductName: '',
  402 + productName: '',
  403 + capacity: '',
  404 + salesChannel: '',
  405 + hasPreferentialPolicy: null,
  406 + investInFutures: null,
  407 + hasPenaltyRecord: null,
  408 + businessScopeMatch: null,
  409 + commonMaterialIssue: '',
  410 + otherIssue: '',
  411 + firstCooperationYear: '',
  412 + isNewDevelopment: '',
  413 + operationMode: '',
  414 + hasFailedPlanRecord: null,
  415 + hasPlanPerformanceIssue: null,
  416 + accountingProcess: '',
  417 + invoiceNameMatch: null,
  418 + outboundProcessStandard: null,
  419 + transportMode: '',
  420 + attachmentFileIds: '',
  421 + attachmentFileNames: '',
  422 + investigatorId: '',
  423 + investigatorName: '',
  424 + purchaseDepartment: '',
  425 + purchaseDepartmentName: '',
  426 + reviewValidUntil: ''
  427 + }
  428 + }
  429 + },
  430 + computed: {
  431 + showCompanyNatureOther() {
  432 + const v = String(this.form.companyNature || '')
  433 + return v.split(',').includes('OTHER')
  434 + }
  435 + },
  436 + async onLoad(query) {
  437 + const id = (query && (query.id || query.code)) ? String(query.id || query.code) : ''
  438 + this.id = id
  439 + await this.loadDicData()
  440 + await this.loadPurchaseDeptOptions()
  441 + await this.loadDetail()
  442 + },
  443 + methods: {
  444 + async loadDicData() {
  445 + try {
  446 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  447 + const next = {
  448 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  449 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  450 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  451 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  452 + }
  453 + this.dicOptions = next
  454 + this.companyNatureOptions = this.dicToSheetOptions(next.COMPANY_NATURE)
  455 + this.developNewOptions = this.dicToSheetOptions(next.DEVELOP_NEW)
  456 + this.operationMethodOptions = this.dicToSheetOptions(next.OPERATION_METHOD)
  457 + this.purchaseSourceOptions = this.dicToSheetOptions(next.PURCHASE_SOURCE)
  458 + } catch (e) {
  459 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  460 + this.companyNatureOptions = []
  461 + this.developNewOptions = []
  462 + this.operationMethodOptions = []
  463 + this.purchaseSourceOptions = []
  464 + uni.showToast({ title: '字典加载失败', icon: 'none' })
  465 + }
  466 + },
  467 + dicToSheetOptions(items) {
  468 + const list = Array.isArray(items) ? items : []
  469 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  470 + },
  471 + async loadPurchaseDeptOptions() {
  472 + try {
  473 + const res = await getPurchaseDeptApi()
  474 + const data = (res && res.data) ? res.data : {}
  475 + this.purchaseDept = (data && typeof data === 'object') ? data : null
  476 + this.form.purchaseDepartment = data && data.id != null ? String(data.id) : ''
  477 + this.form.purchaseDepartmentName = data && data.name != null ? String(data.name) : ''
  478 + } catch (e) {
  479 + this.purchaseDept = null
  480 + this.form.purchaseDepartment = ''
  481 + this.form.purchaseDepartmentName = ''
  482 + }
  483 + },
  484 + displayLabel(field) {
  485 + const m = this.form
  486 + const map = {
  487 + companyNatureName: '请选择公司性质',
  488 + purchaseSource: '请选择',
  489 + operationMode: '请选择',
  490 + isNewDevelopment: '请选择',
  491 + hasPreferentialPolicy: '请选择',
  492 + investInFutures: '请选择',
  493 + hasPenaltyRecord: '请选择',
  494 + businessScopeMatch: '请选择',
  495 + hasFailedPlanRecord: '请选择',
  496 + hasPlanPerformanceIssue: '请选择',
  497 + invoiceNameMatch: '请选择',
  498 + outboundProcessStandard: '请选择'
  499 + }
  500 + if (field === 'companyNatureName') {
  501 + const val = m[field]
  502 + return val ? String(val) : map[field]
  503 + }
  504 + if (field === 'purchaseSource') {
  505 + const v = m.purchaseSource
  506 + return v ? getDicName('PURCHASE_SOURCE', String(v), this.dicOptions.PURCHASE_SOURCE) : map[field]
  507 + }
  508 + if (field === 'operationMode') {
  509 + const v = m.operationMode
  510 + return v ? getDicName('OPERATION_METHOD', String(v), this.dicOptions.OPERATION_METHOD) : map[field]
  511 + }
  512 + if (field === 'isNewDevelopment') {
  513 + const v = m.isNewDevelopment
  514 + return v ? getDicName('DEVELOP_NEW', String(v), this.dicOptions.DEVELOP_NEW) : map[field]
  515 + }
  516 + const v = m[field]
  517 + if (v === true) return '是'
  518 + if (v === false) return '否'
  519 + return map[field] || '请选择'
  520 + },
  521 + openSheet(field) {
  522 + const map = {
  523 + purchaseSource: { title: '收购来源', options: this.purchaseSourceOptions },
  524 + operationMode: { title: '操作方式', options: this.operationMethodOptions },
  525 + isNewDevelopment: { title: '是否新开发', options: this.developNewOptions },
  526 + hasPreferentialPolicy: { title: '是否享有优惠政策', options: this.yesNoOptions },
  527 + investInFutures: { title: '是否投资期货', options: this.yesNoOptions },
  528 + hasPenaltyRecord: { title: '是否有被处罚记录', options: this.yesNoOptions },
  529 + businessScopeMatch: { title: '实际经营范围与法定经营范围是否相符', options: this.yesNoOptions },
  530 + hasFailedPlanRecord: { title: '是否有计划落空的不良记录', options: this.yesNoOptions },
  531 + hasPlanPerformanceIssue: { title: '是否有计划履行不到位现象', options: this.yesNoOptions },
  532 + invoiceNameMatch: { title: '开票品名与出库单品名是否一致', options: this.yesNoOptions },
  533 + outboundProcessStandard: { title: '出库流程是否规范', options: this.yesNoOptions }
  534 + }
  535 + const cfg = map[field]
  536 + if (!cfg) return
  537 + const current = this.form[field]
  538 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  539 + this.sheet = {
  540 + ...this.sheet,
  541 + visible: true,
  542 + title: cfg.title,
  543 + options: cfg.options || [],
  544 + field,
  545 + value: match ? match.value : current
  546 + }
  547 + },
  548 + openMultiSheet(field) {
  549 + if (field !== 'companyNature') return
  550 + this.multiSheet = {
  551 + ...this.multiSheet,
  552 + visible: true,
  553 + title: '公司性质',
  554 + options: this.companyNatureOptions || [],
  555 + field,
  556 + value: this.form.companyNature || ''
  557 + }
  558 + },
  559 + onSheetConfirm({ value }) {
  560 + const field = this.sheet.field
  561 + if (!field) return
  562 + this.form[field] = value
  563 + this.sheet.visible = false
  564 + },
  565 + onMultiSheetConfirm({ value }) {
  566 + const field = this.multiSheet.field
  567 + if (field === 'companyNature') {
  568 + const normalized = this.normalizeCompanyNature(value)
  569 + this.form.companyNature = normalized.value
  570 + this.form.companyNatureName = normalized.label
  571 + if (!this.showCompanyNatureOther) this.form.companyNatureOther = ''
  572 + }
  573 + this.multiSheet.visible = false
  574 + },
  575 + normalizeCompanyNature(valueStr) {
  576 + const selected = (valueStr ? String(valueStr).split(',').filter(Boolean) : [])
  577 + const finalSelected = selected.slice(0)
  578 + const orderedValues = []
  579 + const orderedLabels = []
  580 + ;(this.companyNatureOptions || []).forEach(opt => {
  581 + const v = opt && opt.value != null ? String(opt.value) : ''
  582 + if (v && finalSelected.includes(v)) {
  583 + orderedValues.push(v)
  584 + orderedLabels.push(opt.label != null ? String(opt.label) : '')
  585 + }
  586 + })
  587 + return { value: orderedValues.join(','), label: orderedLabels.join(',') }
  588 + },
  589 + removeAttachment(idx) {
  590 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  591 + list.splice(idx, 1)
  592 + this.attachmentFiles = list
  593 + },
  594 + onAddAttachment(val) {
  595 + const payload = val || { id: '', name: '' }
  596 + if (!payload.id) return
  597 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  598 + list.push(payload)
  599 + this.attachmentFiles = list
  600 + this.newAttachment = { id: '', name: '' }
  601 + },
  602 + onAttachmentInput(idx, val) {
  603 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  604 + list[idx] = val || { id: '', name: '' }
  605 + this.attachmentFiles = list
  606 + },
  607 + validate() {
  608 + const requiredTextFields = [
  609 + { key: 'unitName', label: '单位名称' },
  610 + { key: 'customerShortName', label: '客户简称' },
  611 + { key: 'companyNature', label: '公司性质' },
  612 + { key: 'bankName', label: '开户行' },
  613 + { key: 'bankAccount', label: '账号' },
  614 + { key: 'legalRepresentative', label: '法人代表' },
  615 + { key: 'companyEstablishedTime', label: '公司成立时间' },
  616 + { key: 'address', label: '地址' },
  617 + { key: 'businessPrincipal', label: '业务负责人' },
  618 + { key: 'businessPrincipalPosition', label: '职务' },
  619 + { key: 'businessPrincipalPhone', label: '电话' },
  620 + { key: 'legalBusinessRelation', label: '法人与业务负责人关系' },
  621 + { key: 'factoryOfficeProperty', label: '生产厂房及办公楼产权' },
  622 + { key: 'factoryOfficeArea', label: '生产厂房及办公楼面积' },
  623 + { key: 'warehouseYardProperty', label: '仓库或货场产权' },
  624 + { key: 'warehouseYardArea', label: '仓库或货场产权面积' },
  625 + { key: 'mainEquipment', label: '主要生产设备' },
  626 + { key: 'normalInventory', label: '正常库存量' },
  627 + { key: 'mainVarieties', label: '主要品种' },
  628 + { key: 'monthlyPurchaseVolume', label: '月度收购量' },
  629 + { key: 'purchaseSource', label: '收购来源' },
  630 + { key: 'stockInProductName', label: '入库品名' },
  631 + { key: 'productName', label: '产品名称' },
  632 + { key: 'capacity', label: '产能' },
  633 + { key: 'salesChannel', label: '销售渠道' },
  634 + { key: 'firstCooperationYear', label: '首次合作年份' },
  635 + { key: 'isNewDevelopment', label: '是否新开发' },
  636 + { key: 'operationMode', label: '操作方式' },
  637 + { key: 'accountingProcess', label: '进销账务如何处理' },
  638 + { key: 'transportMode', label: '运输方式' },
  639 + { key: 'commonMaterialIssue', label: '常见料质问题' },
  640 + { key: 'otherIssue', label: '合作中的其它问题' },
  641 + { key: 'purchaseDepartment', label: '采购处' },
  642 + { key: 'reviewValidUntil', label: '评审有效期' },
  643 + { key: 'investigatorId', label: '资信调查人ID' }
  644 + ]
  645 + for (let i = 0; i < requiredTextFields.length; i++) {
  646 + const f = requiredTextFields[i]
  647 + const v = this.form && this.form[f.key]
  648 + if (v == null || String(v).trim() === '') {
  649 + uni.showToast({ title: `${f.label}必填`, icon: 'none' })
  650 + return false
  651 + }
  652 + }
  653 +
  654 + const registeredCapital = Number(this.form.registeredCapital)
  655 + if (!Number.isFinite(registeredCapital) || registeredCapital < 0) {
  656 + uni.showToast({ title: '注册资金请填写数字', icon: 'none' })
  657 + return false
  658 + }
  659 +
  660 + const requiredBoolFields = [
  661 + { key: 'hasPreferentialPolicy', label: '是否享有优惠政策' },
  662 + { key: 'investInFutures', label: '是否投资期货' },
  663 + { key: 'hasPenaltyRecord', label: '是否有被处罚记录' },
  664 + { key: 'businessScopeMatch', label: '经营范围是否相符' },
  665 + { key: 'hasFailedPlanRecord', label: '计划落空不良记录' },
  666 + { key: 'hasPlanPerformanceIssue', label: '计划履行不到位现象' },
  667 + { key: 'invoiceNameMatch', label: '开票品名是否一致' },
  668 + { key: 'outboundProcessStandard', label: '出库流程是否规范' }
  669 + ]
  670 + for (let i = 0; i < requiredBoolFields.length; i++) {
  671 + const f = requiredBoolFields[i]
  672 + const v = this.form && this.form[f.key]
  673 + if (!(v === true || v === false)) {
  674 + uni.showToast({ title: `请选择${f.label}`, icon: 'none' })
  675 + return false
  676 + }
  677 + }
  678 +
  679 + const files = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.filter(it => it && it.id) : []
  680 + if (!files.length) {
  681 + uni.showToast({ title: '请上传附件', icon: 'none' })
  682 + return false
  683 + }
  684 +
  685 + const phone = String(this.form.businessPrincipalPhone || '').trim()
  686 + if (phone && !/^1\d{10}$/.test(phone)) {
  687 + uni.showToast({ title: '电话请输入11位手机号', icon: 'none' })
  688 + return false
  689 + }
  690 + const year = String(this.form.firstCooperationYear || '').trim()
  691 + if (year && !/^\d{4}$/.test(year)) {
  692 + uni.showToast({ title: '首次合作年份请填写4位年份', icon: 'none' })
  693 + return false
  694 + }
  695 + return true
  696 + },
  697 + buildPayload() {
  698 + const payload = { ...this.form }
  699 + if (!this.showCompanyNatureOther) payload.companyNatureOther = ''
  700 + delete payload.companyNatureName
  701 + delete payload.investigatorName
  702 + delete payload.purchaseDepartmentName
  703 + payload.registeredCapital = Number(payload.registeredCapital)
  704 + const files = (Array.isArray(this.attachmentFiles) ? this.attachmentFiles : []).filter(it => it && it.id)
  705 + payload.attachmentFileIds = files.map(it => String(it.id || '')).filter(Boolean).join(',')
  706 + payload.attachmentFileNames = files.map(it => String(it.name || '')).filter(Boolean).join(',')
  707 + return payload
  708 + },
  709 + async onSubmit() {
  710 + if (this.submitting) return
  711 + if (!this.validate()) return
  712 + this.submitting = true
  713 + const payload = this.buildPayload()
  714 + try {
  715 + await domesticCustomerCreditSaveApi(payload)
  716 + uni.showToast({ title: '保存成功', icon: 'success' })
  717 + setTimeout(() => { uni.navigateBack() }, 300)
  718 + } catch (e) {
  719 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  720 + } finally {
  721 + this.submitting = false
  722 + }
  723 + },
  724 + async loadDetail() {
  725 + this.loading = true
  726 + try {
  727 + const res = await domesticCustomerCreditGetApi(this.id)
  728 + const data = res && res.data ? res.data : {}
  729 + const next = { ...this.form, ...(data || {}) }
  730 + if (this.purchaseDept && this.purchaseDept.id != null) {
  731 + next.purchaseDepartment = String(this.purchaseDept.id)
  732 + next.purchaseDepartmentName = this.purchaseDept.name != null ? String(this.purchaseDept.name) : ''
  733 + }
  734 + next.id = next.id || this.id || ''
  735 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  736 + if (!next.investigatorId) next.investigatorId = u && u.id ? String(u.id) : ''
  737 + if (!next.investigatorName) next.investigatorName = u && u.name ? String(u.name) : ''
  738 + this.form = next
  739 + this.form.companyNatureName = this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  740 + this.attachmentFiles = this.normalizeAttachmentFiles(data || next)
  741 + } catch (e) {
  742 + uni.showToast({ title: '加载失败', icon: 'none' })
  743 + } finally {
  744 + this.loading = false
  745 + }
  746 + },
  747 + normalizeAttachmentFiles(raw) {
  748 + if (!raw) return []
  749 + const ids = raw.attachmentFileIds != null ? String(raw.attachmentFileIds) : ''
  750 + const names = raw.attachmentFileNames != null ? String(raw.attachmentFileNames) : ''
  751 + const idArr = ids ? ids.split(',').map(s => s.trim()).filter(Boolean) : []
  752 + const nameArr = names ? names.split(',') : []
  753 + if (idArr.length) {
  754 + return idArr.map((id, i) => ({ id, name: (nameArr[i] != null ? String(nameArr[i]) : '') }))
  755 + }
  756 + const legacy = Array.isArray(raw.attachments) ? raw.attachments : []
  757 + return legacy.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  758 + },
  759 + labelsOf(options, csv) {
  760 + const v = csv == null ? '' : String(csv)
  761 + if (!v) return ''
  762 + const parts = v.split(',').filter(Boolean)
  763 + if (!parts.length) return ''
  764 + const labels = []
  765 + ;(options || []).forEach(opt => {
  766 + const ov = opt && opt.value != null ? String(opt.value) : ''
  767 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  768 + })
  769 + return labels.filter(Boolean).join(',') || ''
  770 + }
  771 + }
  772 +}
  773 +</script>
  774 +
  775 +<style lang="scss" scoped>
  776 +.page {
  777 + display: flex;
  778 + flex-direction: column;
  779 + height: 100%;
  780 +}
  781 +
  782 +.scroll {
  783 + flex: 1;
  784 + padding: 12rpx 0 160rpx;
  785 +}
  786 +
  787 +.footer {
  788 + position: fixed;
  789 + left: 0;
  790 + right: 0;
  791 + bottom: 0;
  792 + padding: 32rpx;
  793 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  794 + background: #fff;
  795 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  796 + z-index: 10;
  797 +
  798 + .btn {
  799 + height: 80rpx;
  800 + line-height: 80rpx;
  801 + border-radius: 12rpx;
  802 + font-size: 32rpx;
  803 + }
  804 +
  805 + .submit {
  806 + background: $theme-primary;
  807 + color: #fff;
  808 + }
  809 +}
  810 +
  811 +.title-header {
  812 + display: flex;
  813 + align-items: center;
  814 + padding: 24rpx 32rpx 12rpx;
  815 + background-color: #ffffff;
  816 + .title-header_icon {
  817 + width: 36rpx;
  818 + height: 36rpx;
  819 + margin-right: 12rpx;
  820 + }
  821 +
  822 + span {
  823 + font-size: 34rpx;
  824 + font-weight: 600;
  825 + color: rgba(0, 0, 0, 0.9);
  826 + }
  827 +}
  828 +
  829 +.mgb10 {
  830 + margin-bottom: 20rpx;
  831 +}
  832 +
  833 +.amount-row {
  834 + display: flex;
  835 + align-items: center;
  836 + gap: 12rpx;
  837 +
  838 + .unit, .prefix, .suffix {
  839 + font-size: 28rpx;
  840 + color: rgba(0, 0, 0, 0.6);
  841 + white-space: nowrap;
  842 + }
  843 +}
  844 +
  845 +.attach-box {
  846 + display: flex;
  847 + flex-direction: column;
  848 + align-items: flex-end;
  849 + gap: 16rpx;
  850 + width: 100%;
  851 +}
  852 +
  853 +.attach-row {
  854 + width: 100%;
  855 + display: flex;
  856 + justify-content: flex-end;
  857 + align-items: center;
  858 + gap: 20rpx;
  859 +}
  860 +
  861 +.attach-del {
  862 + font-size: 28rpx;
  863 + color: #D54941;
  864 +}
  865 +
  866 +::v-deep .uni-list {
  867 + .uni-easyinput {
  868 + display: flex;
  869 +
  870 + .uni-input-input {
  871 + color: rgba(0, 0, 0, 0.9);
  872 + }
  873 + }
  874 +
  875 + .uni-input-placeholder {
  876 + z-index: 1;
  877 + }
  878 +
  879 + .uni-input-input {
  880 + background-color: #ffffff;
  881 + }
  882 +
  883 + background: transparent;
  884 +
  885 + &-item {
  886 + &__extra-text {
  887 + font-size: 32rpx;
  888 + }
  889 +
  890 + &__content-title {
  891 + font-size: 32rpx;
  892 + color: rgba(0, 0, 0, 0.9);
  893 + }
  894 +
  895 + &__container {
  896 + padding: 32rpx;
  897 +
  898 + .uni-easyinput {
  899 + &__placeholder-class {
  900 + font-size: 32rpx;
  901 + color: rgba(0, 0, 0, 0.4);
  902 + }
  903 +
  904 + &__content {
  905 + border: none;
  906 + background-color: #ffffff !important;
  907 +
  908 + &-input {
  909 + padding-left: 0 !important;
  910 + height: 48rpx;
  911 + line-height: 48rpx;
  912 + font-size: 32rpx;
  913 + }
  914 +
  915 + .content-clear-icon {
  916 + font-size: 44rpx !important;
  917 + }
  918 + }
  919 + }
  920 +
  921 + .item-title,
  922 + .uni-list-item__content {
  923 + flex: none;
  924 + min-height: 48rpx;
  925 + line-height: 48rpx;
  926 + font-size: 32rpx;
  927 + position: relative;
  928 + width: 210rpx;
  929 + margin-right: 32rpx;
  930 + color: rgba(0, 0, 0, 0.9);
  931 +
  932 + .required {
  933 + color: red;
  934 + position: absolute;
  935 + top: 50%;
  936 + transform: translateY(-50%);
  937 + left: -16rpx;
  938 + }
  939 + }
  940 + }
  941 +
  942 + &.select-item {
  943 + &.is-empty {
  944 + .uni-list-item__extra-text {
  945 + color: rgba(0, 0, 0, 0.4) !important;
  946 + }
  947 + }
  948 +
  949 + &.is-filled {
  950 + .uni-list-item__extra-text {
  951 + color: rgba(0, 0, 0, 0.9) !important;
  952 + }
  953 + }
  954 + }
  955 +
  956 + &.mgb10 {
  957 + margin-bottom: 20rpx;
  958 + }
  959 + }
  960 +}
  961 +</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.unitName" placeholder="请输入" :inputBorder="false" />
  13 + </template>
  14 + </uni-list-item>
  15 +
  16 + <uni-list-item class="select-item" :class="form.companyNature ? 'is-filled' : 'is-empty'" clickable
  17 + @click="openSheet('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 +
  23 + <uni-list-item title="法人代表">
  24 + <template v-slot:footer>
  25 + <uni-easyinput v-model="form.legalRepresentative" placeholder="请输入" :inputBorder="false" />
  26 + </template>
  27 + </uni-list-item>
  28 +
  29 + <uni-list-item title="电话及传真">
  30 + <template v-slot:footer>
  31 + <uni-easyinput v-model="form.phoneAndFax" placeholder="请输入" :inputBorder="false" />
  32 + </template>
  33 + </uni-list-item>
  34 +
  35 + <uni-list-item title="注册证书号">
  36 + <template v-slot:footer>
  37 + <uni-easyinput v-model="form.registrationCertificateNo" placeholder="请输入" :inputBorder="false" />
  38 + </template>
  39 + </uni-list-item>
  40 +
  41 + <uni-list-item title="地址">
  42 + <template v-slot:footer>
  43 + <uni-easyinput v-model="form.address" placeholder="请输入" :inputBorder="false" />
  44 + </template>
  45 + </uni-list-item>
  46 +
  47 + <uni-list-item title="国内业务负责人">
  48 + <template v-slot:footer>
  49 + <uni-easyinput v-model="form.domesticBusinessPrincipal" placeholder="请输入" :inputBorder="false" />
  50 + </template>
  51 + </uni-list-item>
  52 +
  53 + <uni-list-item title="负责人身份证/护照号">
  54 + <template v-slot:footer>
  55 + <uni-easyinput v-model="form.principalCertificateNo" placeholder="请输入" :inputBorder="false" />
  56 + </template>
  57 + </uni-list-item>
  58 +
  59 + <uni-list-item title="成立时间及货场规模">
  60 + <template v-slot:footer>
  61 + <uni-easyinput type="textarea" v-model="form.establishedTimeAndYardScale" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  62 + </template>
  63 + </uni-list-item>
  64 +
  65 + <uni-list-item title="经营品种、规模">
  66 + <template v-slot:footer>
  67 + <uni-easyinput type="textarea" v-model="form.overallBusinessVarietiesScale" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  68 + </template>
  69 + </uni-list-item>
  70 +
  71 + <uni-list-item title="出口到国内时间">
  72 + <template v-slot:footer>
  73 + <uni-easyinput v-model="form.exportToDomesticTime" placeholder="请输入" :inputBorder="false" />
  74 + </template>
  75 + </uni-list-item>
  76 +
  77 + <uni-list-item title="出口规模、品种">
  78 + <template v-slot:footer>
  79 + <uni-easyinput type="textarea" v-model="form.exportToDomesticScaleVarieties" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  80 + </template>
  81 + </uni-list-item>
  82 +
  83 + <uni-list-item title="与国内合作企业">
  84 + <template v-slot:footer>
  85 + <uni-easyinput type="textarea" v-model="form.cooperatingDomesticCompanies" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  86 + </template>
  87 + </uni-list-item>
  88 +
  89 + <uni-list-item title="合作效果">
  90 + <template v-slot:footer>
  91 + <uni-easyinput type="textarea" v-model="form.cooperationEffect" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  92 + </template>
  93 + </uni-list-item>
  94 +
  95 + <uni-list-item title="供应商考察">
  96 + <template v-slot:footer>
  97 + <uni-easyinput type="textarea" v-model="form.supplierInspection" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  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.domesticSalesOfficeInspection" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  104 + </template>
  105 + </uni-list-item>
  106 +
  107 + <uni-list-item title="有无担保函">
  108 + <template v-slot:footer>
  109 + <uni-easyinput v-model="form.guaranteeLetter" placeholder="请输入" :inputBorder="false" />
  110 + </template>
  111 + </uni-list-item>
  112 +
  113 + <uni-list-item title="合同纠纷">
  114 + <template v-slot:footer>
  115 + <uni-easyinput type="textarea" v-model="form.contractDispute" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  116 + </template>
  117 + </uni-list-item>
  118 +
  119 + <uni-list-item title="保险、运输方式">
  120 + <template v-slot:footer>
  121 + <uni-easyinput v-model="form.insuranceTransportMode" placeholder="请输入" :inputBorder="false" />
  122 + </template>
  123 + </uni-list-item>
  124 +
  125 + <uni-list-item title="滞箱滞报费用">
  126 + <template v-slot:footer>
  127 + <uni-easyinput v-model="form.detentionDemurrageFee" placeholder="请输入" :inputBorder="false" />
  128 + </template>
  129 + </uni-list-item>
  130 +
  131 + <uni-list-item title="操作品种">
  132 + <template v-slot:footer>
  133 + <uni-easyinput v-model="form.operationVariety" placeholder="请输入" :inputBorder="false" />
  134 + </template>
  135 + </uni-list-item>
  136 +
  137 + <uni-list-item title="操作规模">
  138 + <template v-slot:footer>
  139 + <uni-easyinput v-model="form.operationScale" placeholder="请输入" :inputBorder="false" />
  140 + </template>
  141 + </uni-list-item>
  142 +
  143 + <uni-list-item title="定价模式">
  144 + <template v-slot:footer>
  145 + <uni-easyinput v-model="form.pricingMode" placeholder="请输入" :inputBorder="false" />
  146 + </template>
  147 + </uni-list-item>
  148 +
  149 + <uni-list-item title="结算方式">
  150 + <template v-slot:footer>
  151 + <uni-easyinput v-model="form.settlementMethod" placeholder="请输入" :inputBorder="false" />
  152 + </template>
  153 + </uni-list-item>
  154 +
  155 + <uni-list-item title="磅差约定">
  156 + <template v-slot:footer>
  157 + <uni-easyinput v-model="form.weightDifferenceAgreement" placeholder="请输入" :inputBorder="false" />
  158 + </template>
  159 + </uni-list-item>
  160 +
  161 + <uni-list-item class="mgb10" title="质量标准">
  162 + <template v-slot:footer>
  163 + <uni-easyinput v-model="form.qualityStandard" placeholder="请输入" :inputBorder="false" />
  164 + </template>
  165 + </uni-list-item>
  166 +
  167 + <view class="title-header">
  168 + <image class="title-header_icon" src="/static/images/title.png" />
  169 + <span>供应商分类</span>
  170 + </view>
  171 +
  172 + <uni-list-item class="select-item" :class="form.supplierCategory ? 'is-filled' : 'is-empty'" clickable
  173 + @click="openSheet('supplierCategory')" :rightText="displayLabel('supplierCategory')" showArrow>
  174 + <template v-slot:body>
  175 + <view class="item-title"><text>供应商分类</text></view>
  176 + </template>
  177 + </uni-list-item>
  178 +
  179 + <uni-list-item v-if="form.supplierCategory" class="mgb10" title="分类说明">
  180 + <template v-slot:footer>
  181 + <uni-easyinput type="textarea" :value="supplierCategoryDesc" :inputBorder="false" disabled placeholder="选择供应商分类后自动显示" maxlength="2000" />
  182 + </template>
  183 + </uni-list-item>
  184 +
  185 + <view class="title-header">
  186 + <image class="title-header_icon" src="/static/images/title.png" />
  187 + <span>操作方案</span>
  188 + </view>
  189 +
  190 + <uni-list-item title="操作时间">
  191 + <template v-slot:footer>
  192 + <uni-easyinput v-model="form.schemeOperationTime" placeholder="请输入" :inputBorder="false" />
  193 + </template>
  194 + </uni-list-item>
  195 +
  196 + <uni-list-item title="操作模式">
  197 + <template v-slot:footer>
  198 + <uni-easyinput v-model="form.schemeOperationMode" placeholder="请输入" :inputBorder="false" />
  199 + </template>
  200 + </uni-list-item>
  201 +
  202 + <uni-list-item title="操作品种">
  203 + <template v-slot:footer>
  204 + <uni-easyinput v-model="form.schemeOperationVariety" placeholder="请输入" :inputBorder="false" />
  205 + </template>
  206 + </uni-list-item>
  207 +
  208 + <uni-list-item title="操作数量">
  209 + <template v-slot:footer>
  210 + <uni-easyinput v-model="form.schemeOperationQuantity" placeholder="请输入" :inputBorder="false" />
  211 + </template>
  212 + </uni-list-item>
  213 +
  214 + <uni-list-item title="发货要求">
  215 + <template v-slot:footer>
  216 + <uni-easyinput type="textarea" v-model="form.shippingRequirement" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  217 + </template>
  218 + </uni-list-item>
  219 +
  220 + <uni-list-item title="付款方式">
  221 + <template v-slot:footer>
  222 + <uni-easyinput v-model="form.paymentMethod" placeholder="请输入" :inputBorder="false" />
  223 + </template>
  224 + </uni-list-item>
  225 +
  226 + <uni-list-item title="下次评审时间">
  227 + <template v-slot:footer>
  228 + <uni-datetime-picker type="date" v-model="form.nextReviewTime" />
  229 + </template>
  230 + </uni-list-item>
  231 +
  232 + <uni-list-item title="评审部门">
  233 + <template v-slot:footer>
  234 + <uni-easyinput v-model="form.reviewDepartment" placeholder="请输入" :inputBorder="false" />
  235 + </template>
  236 + </uni-list-item>
  237 +
  238 + <uni-list-item title="资信调查人">
  239 + <template v-slot:footer>
  240 + <uni-easyinput v-model="form.investigatorName" :inputBorder="false" disabled />
  241 + </template>
  242 + </uni-list-item>
  243 +
  244 + <uni-list-item class="mgb10" title="采购处">
  245 + <template v-slot:footer>
  246 + <uni-easyinput v-model="form.purchaseDepartmentName" :inputBorder="false" disabled />
  247 + </template>
  248 + </uni-list-item>
  249 + </uni-list>
  250 + </scroll-view>
  251 +
  252 + <view class="footer">
  253 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '提交中...' : '提交' }}</button>
  254 + </view>
  255 +
  256 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  257 + @confirm="onSheetConfirm" />
  258 + </view>
  259 +</template>
  260 +
  261 +<script>
  262 +import SingleSelectSheet from '@/components/single-select/index.vue'
  263 +import { getDicByCodes } from '@/utils/dic.js'
  264 +import { foreignTradeCreditSaveApi, getPurchaseDeptApi } from '@/api/procure-manage/foreignTradeCredit.js'
  265 +
  266 +export default {
  267 + name: 'ForeignTradeAdd',
  268 + components: { SingleSelectSheet },
  269 + data() {
  270 + return {
  271 + submitting: false,
  272 + supplierCategoryOptions: [
  273 + { label: 'A类供应商', value: 'A' },
  274 + { label: 'B类供应商', value: 'B' },
  275 + { label: 'C类供应商', value: 'C' },
  276 + { label: 'D类供应商', value: 'D' }
  277 + ],
  278 + companyNatureOptions: [],
  279 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  280 + form: {
  281 + id: '',
  282 + unitName: '',
  283 + companyNature: '',
  284 + companyNatureName: '',
  285 + legalRepresentative: '',
  286 + phoneAndFax: '',
  287 + registrationCertificateNo: '',
  288 + address: '',
  289 + domesticBusinessPrincipal: '',
  290 + principalCertificateNo: '',
  291 + establishedTimeAndYardScale: '',
  292 + overallBusinessVarietiesScale: '',
  293 + exportToDomesticTime: '',
  294 + exportToDomesticScaleVarieties: '',
  295 + cooperatingDomesticCompanies: '',
  296 + cooperationEffect: '',
  297 + supplierInspection: '',
  298 + domesticSalesOfficeInspection: '',
  299 + guaranteeLetter: '',
  300 + contractDispute: '',
  301 + insuranceTransportMode: '',
  302 + detentionDemurrageFee: '',
  303 + operationVariety: '',
  304 + operationScale: '',
  305 + pricingMode: '',
  306 + settlementMethod: '',
  307 + weightDifferenceAgreement: '',
  308 + qualityStandard: '',
  309 + supplierCategory: '',
  310 + schemeOperationTime: '',
  311 + schemeOperationMode: '',
  312 + schemeOperationVariety: '',
  313 + schemeOperationQuantity: '',
  314 + shippingRequirement: '',
  315 + paymentMethod: '',
  316 + nextReviewTime: '',
  317 + reviewDepartment: '',
  318 + investigatorId: '',
  319 + investigatorName: '',
  320 + purchaseDepartment: '',
  321 + purchaseDepartmentName: ''
  322 + }
  323 + }
  324 + },
  325 + created() {
  326 + this.loadDicData()
  327 + this.loadPurchaseDeptOptions()
  328 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  329 + this.form.investigatorId = u && u.id ? String(u.id) : ''
  330 + this.form.investigatorName = u && u.name ? String(u.name) : ''
  331 + },
  332 + computed: {
  333 + supplierCategoryDesc() {
  334 + const v = this.form && this.form.supplierCategory != null ? String(this.form.supplierCategory) : ''
  335 + const map = {
  336 + A: '资信调查有担保函无资金风险、资料齐全,料质可控,价格较好,若出现质量、磅差问题可以索赔解决,进口倒挂时可协商延迟点价,可推迟发货,可试操作(前3个月每月操作量300-500吨);第一次计划货到厂验收结束后进行评审,正常后可以增量操作,要求每年评审一次;',
  337 + B: '资信调查无担保函,国外企业属国内企业控股,无资金风险、资料齐全,价格较好,料质可控,若出现质量、磅差问题可以索赔解决(前3个月每月操作量200-400吨),第一次货到厂验收合格后可增量操作;操作正常每年评审一次;',
  338 + C: '资信调查无担保函,资料齐全,料质可控,价格一般,出现质量、磅差问题可以索赔解决,可试单限量操作(前3个月每月操作量100-200吨),第一次货到厂验收合格后可增量操作,新开发供应商首年操作按每半年评审一次,操作正常则次年调整为每年评审一次;若出现索赔问题不及时解决可中止后续开信用证和中止到港货物的DP/TT付款,且立即暂停业务操作。',
  339 + D: '资信调查无担保函,通过委托第三方机构调查无风险,虽然资料不齐全,但料质可控,价格略高,出现质量、磅差问题索赔解决有难度,一单一议,D类供应商第一次货到厂验收、付款、退款或者索赔正常后,可继续操作逐步增量(每月操作量100-200吨),每半年评审一次,操作正常到则次年调整为每年评审一次;若出现索赔问题不及时解决可终止后续到港货物的付款,且立即停止业务操作。'
  340 + }
  341 + return map[v] || ''
  342 + }
  343 + },
  344 + methods: {
  345 + async loadDicData() {
  346 + try {
  347 + const results = await getDicByCodes(['COMPANY_NATURE'])
  348 + const items = results && results.COMPANY_NATURE && results.COMPANY_NATURE.data ? results.COMPANY_NATURE.data : []
  349 + this.companyNatureOptions = (Array.isArray(items) ? items : []).map(it => ({
  350 + label: it && it.name != null ? String(it.name) : '',
  351 + value: it && it.code != null ? String(it.code) : ''
  352 + })).filter(it => it.value)
  353 + } catch (e) {
  354 + this.companyNatureOptions = []
  355 + }
  356 + },
  357 + async loadPurchaseDeptOptions() {
  358 + try {
  359 + const res = await getPurchaseDeptApi()
  360 + const data = (res && res.data) ? res.data : {}
  361 + this.form.purchaseDepartment = data && data.id != null ? String(data.id) : ''
  362 + this.form.purchaseDepartmentName = data && data.name != null ? String(data.name) : ''
  363 + } catch (e) {
  364 + this.form.purchaseDepartment = ''
  365 + this.form.purchaseDepartmentName = ''
  366 + }
  367 + },
  368 + displayLabel(field) {
  369 + const m = this.form || {}
  370 + const map = {
  371 + companyNatureName: '请选择',
  372 + supplierCategory: '请选择'
  373 + }
  374 + if (field === 'supplierCategory') {
  375 + const code = m.supplierCategory
  376 + const found = (this.supplierCategoryOptions || []).find(o => String(o.value) === String(code))
  377 + return found ? String(found.label || '') : map[field]
  378 + }
  379 + const v = m[field]
  380 + if (v != null && String(v).trim()) return String(v)
  381 + return map[field] || '请选择'
  382 + },
  383 + openSheet(field) {
  384 + const map = {
  385 + companyNature: { title: '公司性质', options: this.companyNatureOptions, valueField: 'companyNature', labelField: 'companyNatureName' },
  386 + supplierCategory: { title: '供应商分类', options: this.supplierCategoryOptions, valueField: 'supplierCategory', labelField: '' }
  387 + }
  388 + const cfg = map[field]
  389 + if (!cfg) return
  390 + const current = this.form[cfg.valueField]
  391 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  392 + this.sheet = {
  393 + ...this.sheet,
  394 + visible: true,
  395 + title: cfg.title,
  396 + options: cfg.options || [],
  397 + field,
  398 + value: match ? match.value : current
  399 + }
  400 + },
  401 + onSheetConfirm({ value, label }) {
  402 + const field = this.sheet.field
  403 + if (field === 'companyNature') this.form.companyNatureName = label
  404 + if (field === 'supplierCategory') {
  405 + this.form.supplierCategory = value
  406 + }
  407 + if (field === 'companyNature') this.form.companyNature = value
  408 + this.sheet.visible = false
  409 + },
  410 + validate() {
  411 + const requiredFields = [
  412 + { key: 'unitName', label: '单位名称' },
  413 + { key: 'companyNature', label: '公司性质' },
  414 + { key: 'legalRepresentative', label: '法人代表' },
  415 + { key: 'phoneAndFax', label: '电话及传真' },
  416 + { key: 'registrationCertificateNo', label: '注册证书号' },
  417 + { key: 'address', label: '地址' },
  418 + { key: 'domesticBusinessPrincipal', label: '国内业务负责人' },
  419 + { key: 'principalCertificateNo', label: '负责人身份证/护照号' },
  420 + { key: 'establishedTimeAndYardScale', label: '成立时间及货场规模' },
  421 + { key: 'overallBusinessVarietiesScale', label: '经营品种、规模' },
  422 + { key: 'exportToDomesticTime', label: '出口到国内时间' },
  423 + { key: 'exportToDomesticScaleVarieties', label: '出口规模、品种' },
  424 + { key: 'cooperatingDomesticCompanies', label: '与国内合作企业' },
  425 + { key: 'cooperationEffect', label: '合作效果' },
  426 + { key: 'supplierInspection', label: '供应商考察' },
  427 + { key: 'domesticSalesOfficeInspection', label: '销售代表办公地考察' },
  428 + { key: 'guaranteeLetter', label: '有无担保函' },
  429 + { key: 'contractDispute', label: '合同纠纷' },
  430 + { key: 'insuranceTransportMode', label: '保险、运输方式' },
  431 + { key: 'detentionDemurrageFee', label: '滞箱滞报费用' },
  432 + { key: 'operationVariety', label: '操作品种' },
  433 + { key: 'operationScale', label: '操作规模' },
  434 + { key: 'pricingMode', label: '定价模式' },
  435 + { key: 'settlementMethod', label: '结算方式' },
  436 + { key: 'weightDifferenceAgreement', label: '磅差约定' },
  437 + { key: 'qualityStandard', label: '质量标准' },
  438 + { key: 'supplierCategory', label: '供应商分类' },
  439 + { key: 'schemeOperationTime', label: '操作时间' },
  440 + { key: 'schemeOperationMode', label: '操作模式' },
  441 + { key: 'schemeOperationVariety', label: '操作品种' },
  442 + { key: 'schemeOperationQuantity', label: '操作数量' },
  443 + { key: 'shippingRequirement', label: '发货要求' },
  444 + { key: 'paymentMethod', label: '付款方式' },
  445 + { key: 'nextReviewTime', label: '下次评审时间' },
  446 + { key: 'reviewDepartment', label: '评审部门' },
  447 + { key: 'investigatorId', label: '资信调查人ID' },
  448 + { key: 'purchaseDepartment', label: '采购处' }
  449 + ]
  450 + for (let i = 0; i < requiredFields.length; i++) {
  451 + const f = requiredFields[i]
  452 + const v = this.form && this.form[f.key]
  453 + if (v == null || String(v).trim() === '') {
  454 + uni.showToast({ title: `${f.label}必填`, icon: 'none' })
  455 + return false
  456 + }
  457 + }
  458 + return true
  459 + },
  460 + buildPayload() {
  461 + return { ...this.form }
  462 + },
  463 + async onSubmit() {
  464 + if (this.submitting) return
  465 + if (!this.validate()) return
  466 + this.submitting = true
  467 + const payload = this.buildPayload()
  468 + try {
  469 + await foreignTradeCreditSaveApi(payload)
  470 + uni.showToast({ title: '提交成功', icon: 'success' })
  471 + try { uni.setStorageSync('FOREIGN_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  472 + setTimeout(() => { uni.navigateBack() }, 300)
  473 + } catch (e) {
  474 + uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
  475 + } finally {
  476 + this.submitting = false
  477 + }
  478 + },
  479 + }
  480 +}
  481 +</script>
  482 +
  483 +<style lang="scss" scoped>
  484 +.page {
  485 + display: flex;
  486 + flex-direction: column;
  487 + height: 100%;
  488 +}
  489 +
  490 +.scroll {
  491 + flex: 1;
  492 + padding: 12rpx 0 160rpx;
  493 +}
  494 +
  495 +.footer {
  496 + position: fixed;
  497 + left: 0;
  498 + right: 0;
  499 + bottom: 0;
  500 + padding: 32rpx;
  501 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  502 + background: #fff;
  503 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  504 + z-index: 10;
  505 +
  506 + .btn {
  507 + height: 80rpx;
  508 + line-height: 80rpx;
  509 + border-radius: 12rpx;
  510 + font-size: 32rpx;
  511 + }
  512 +
  513 + .submit {
  514 + background: $theme-primary;
  515 + color: #fff;
  516 + }
  517 +}
  518 +
  519 +.title-header {
  520 + display: flex;
  521 + align-items: center;
  522 + padding: 24rpx 32rpx 12rpx;
  523 + background-color: #ffffff;
  524 +
  525 + .title-header_icon {
  526 + width: 36rpx;
  527 + height: 36rpx;
  528 + margin-right: 12rpx;
  529 + }
  530 +
  531 + span {
  532 + font-size: 34rpx;
  533 + font-weight: 600;
  534 + color: rgba(0, 0, 0, 0.9);
  535 + }
  536 +}
  537 +
  538 +.mgb10 {
  539 + margin-bottom: 20rpx;
  540 +}
  541 +
  542 +::v-deep .uni-list {
  543 + .uni-easyinput {
  544 + display: flex;
  545 +
  546 + .uni-input-input {
  547 + color: rgba(0, 0, 0, 0.9);
  548 + }
  549 + }
  550 +
  551 + .uni-input-placeholder {
  552 + z-index: 1;
  553 + }
  554 +
  555 + .uni-input-input {
  556 + background-color: #ffffff;
  557 + }
  558 +
  559 + background: transparent;
  560 +
  561 + &-item {
  562 + &__extra-text {
  563 + font-size: 32rpx;
  564 + }
  565 +
  566 + &__content-title {
  567 + font-size: 32rpx;
  568 + color: rgba(0, 0, 0, 0.9);
  569 + }
  570 +
  571 + &__container {
  572 + padding: 32rpx;
  573 +
  574 + .uni-easyinput {
  575 + &__placeholder-class {
  576 + font-size: 32rpx;
  577 + color: rgba(0, 0, 0, 0.4);
  578 + }
  579 +
  580 + &__content {
  581 + border: none;
  582 + background-color: #ffffff !important;
  583 +
  584 + &-input {
  585 + padding-left: 0 !important;
  586 + height: 48rpx;
  587 + line-height: 48rpx;
  588 + font-size: 32rpx;
  589 + }
  590 +
  591 + .content-clear-icon {
  592 + font-size: 44rpx !important;
  593 + }
  594 + }
  595 + }
  596 +
  597 + .item-title,
  598 + .uni-list-item__content {
  599 + flex: none;
  600 + min-height: 48rpx;
  601 + line-height: 48rpx;
  602 + font-size: 32rpx;
  603 + position: relative;
  604 + width: 260rpx;
  605 + margin-right: 32rpx;
  606 + color: rgba(0, 0, 0, 0.9);
  607 + }
  608 + }
  609 +
  610 + &.select-item {
  611 + &.is-empty {
  612 + .uni-list-item__extra-text {
  613 + color: rgba(0, 0, 0, 0.4) !important;
  614 + }
  615 + }
  616 +
  617 + &.is-filled {
  618 + .uni-list-item__extra-text {
  619 + color: rgba(0, 0, 0, 0.9) !important;
  620 + }
  621 + }
  622 + }
  623 +
  624 + &.mgb10 {
  625 + margin-bottom: 20rpx;
  626 + }
  627 + }
  628 +}
  629 +</style>
  630 +
  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.unitName) }}</text>
  7 + <view class="row"><text class="label">公司性质</text><text class="value">{{ safeText(companyNatureText) }}</text></view>
  8 + <view class="row"><text class="label">法人代表</text><text class="value">{{ safeText(form.legalRepresentative) }}</text></view>
  9 + <view class="row"><text class="label">电话及传真</text><text class="value">{{ safeText(form.phoneAndFax) }}</text></view>
  10 + <view class="row"><text class="label">注册证书号</text><text class="value">{{ safeText(form.registrationCertificateNo) }}</text></view>
  11 + <view class="row"><text class="label">地址</text><text class="value">{{ safeText(form.address) }}</text></view>
  12 + <view class="row"><text class="label">国内业务负责人</text><text class="value">{{ safeText(form.domesticBusinessPrincipal) }}</text></view>
  13 + <view class="row"><text class="label">负责人身份证/护照号</text><text class="value">{{ safeText(form.principalCertificateNo) }}</text></view>
  14 + <view class="row"><text class="label">成立时间及货场规模</text><text class="value pre">{{ safeText(form.establishedTimeAndYardScale) }}</text></view>
  15 + <view class="row"><text class="label">经营品种、规模</text><text class="value pre">{{ safeText(form.overallBusinessVarietiesScale) }}</text></view>
  16 + <view class="row"><text class="label">出口到国内时间</text><text class="value">{{ safeText(form.exportToDomesticTime) }}</text></view>
  17 + <view class="row"><text class="label">出口规模、品种</text><text class="value pre">{{ safeText(form.exportToDomesticScaleVarieties) }}</text></view>
  18 + <view class="row"><text class="label">与国内合作企业</text><text class="value pre">{{ safeText(form.cooperatingDomesticCompanies) }}</text></view>
  19 + <view class="row"><text class="label">合作效果</text><text class="value pre">{{ safeText(form.cooperationEffect) }}</text></view>
  20 + <view class="row"><text class="label">供应商考察</text><text class="value pre">{{ safeText(form.supplierInspection) }}</text></view>
  21 + <view class="row"><text class="label">销售代表办公地考察</text><text class="value pre">{{ safeText(form.domesticSalesOfficeInspection) }}</text></view>
  22 + <view class="row"><text class="label">有无担保函</text><text class="value">{{ safeText(form.guaranteeLetter) }}</text></view>
  23 + <view class="row"><text class="label">合同纠纷</text><text class="value pre">{{ safeText(form.contractDispute) }}</text></view>
  24 + <view class="row"><text class="label">保险、运输方式</text><text class="value">{{ safeText(form.insuranceTransportMode) }}</text></view>
  25 + <view class="row"><text class="label">滞箱滞报费用</text><text class="value">{{ safeText(form.detentionDemurrageFee) }}</text></view>
  26 + <view class="row"><text class="label">操作品种</text><text class="value">{{ safeText(form.operationVariety) }}</text></view>
  27 + <view class="row"><text class="label">操作规模</text><text class="value">{{ safeText(form.operationScale) }}</text></view>
  28 + <view class="row"><text class="label">定价模式</text><text class="value">{{ safeText(form.pricingMode) }}</text></view>
  29 + <view class="row"><text class="label">结算方式</text><text class="value">{{ safeText(form.settlementMethod) }}</text></view>
  30 + <view class="row"><text class="label">磅差约定</text><text class="value">{{ safeText(form.weightDifferenceAgreement) }}</text></view>
  31 + <view class="row"><text class="label">质量标准</text><text class="value">{{ safeText(form.qualityStandard) }}</text></view>
  32 + </view>
  33 +
  34 + <view class="title-header">
  35 + <image class="title-header_icon" src="/static/images/title.png" />
  36 + <span>供应商分类</span>
  37 + </view>
  38 + <view class="section">
  39 + <view class="row"><text class="label">供应商分类</text><text class="value">{{ safeText(supplierCategoryName) }}</text></view>
  40 + <view class="row"><text class="label">分类说明</text><text class="value pre">{{ safeText(supplierCategoryDesc) }}</text></view>
  41 + </view>
  42 +
  43 + <view class="title-header">
  44 + <image class="title-header_icon" src="/static/images/title.png" />
  45 + <span>操作方案</span>
  46 + </view>
  47 + <view class="section">
  48 + <view class="row"><text class="label">操作时间</text><text class="value">{{ safeText(form.schemeOperationTime) }}</text></view>
  49 + <view class="row"><text class="label">操作模式</text><text class="value">{{ safeText(form.schemeOperationMode) }}</text></view>
  50 + <view class="row"><text class="label">操作品种</text><text class="value">{{ safeText(form.schemeOperationVariety) }}</text></view>
  51 + <view class="row"><text class="label">操作数量</text><text class="value">{{ safeText(form.schemeOperationQuantity) }}</text></view>
  52 + <view class="row"><text class="label">发货要求</text><text class="value pre">{{ safeText(form.shippingRequirement) }}</text></view>
  53 + <view class="row"><text class="label">付款方式</text><text class="value">{{ safeText(form.paymentMethod) }}</text></view>
  54 + <view class="row"><text class="label">下次评审时间</text><text class="value">{{ safeText(form.nextReviewTime) }}</text></view>
  55 + <view class="row"><text class="label">评审部门</text><text class="value">{{ safeText(form.reviewDepartment) }}</text></view>
  56 + <view class="row"><text class="label">资信调查人</text><text class="value">{{ safeText(form.investigatorName) }}</text></view>
  57 + <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(purchaseDeptName) }}</text></view>
  58 + <view v-if="reviewHint" class="hint">{{ reviewHint }}</view>
  59 + </view>
  60 +
  61 + <view v-if="auditStatusText !== '-'" class="section">
  62 + <view class="row"><text class="label">审核状态</text><text class="value">{{ auditStatusText }}</text></view>
  63 + </view>
  64 + </view>
  65 + </scroll-view>
  66 +
  67 + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" />
  68 + </view>
  69 +</template>
  70 +
  71 +<script>
  72 +import DetailButtons from '@/components/detail-buttons/index.vue'
  73 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  74 +import { foreignTradeCreditCancelApi, foreignTradeCreditGetApi, getPurchaseDeptApi } from '@/api/procure-manage/foreignTradeCredit.js'
  75 +
  76 +export default {
  77 + name: 'ForeignTradeDetail',
  78 + components: { DetailButtons },
  79 + data() {
  80 + return {
  81 + id: '',
  82 + loading: false,
  83 + form: {},
  84 + dicOptions: {
  85 + AUDIT_STATUS: [],
  86 + COMPANY_NATURE: []
  87 + },
  88 + purchaseDept: null,
  89 + buttons: [{
  90 + text: '审核详情',
  91 + visible: true,
  92 + variant: 'outline',
  93 + event: 'auditDetail',
  94 + },{
  95 + text: '审核',
  96 + visible: true,
  97 + variant: 'primary',
  98 + event: 'audit',
  99 + },{
  100 + text: '编辑',
  101 + visible: true,
  102 + variant: 'outline',
  103 + event: 'edit',
  104 + },{
  105 + text: '取消',
  106 + visible: true,
  107 + variant: 'outline',
  108 + event: 'cancel',
  109 + }]
  110 + }
  111 + },
  112 + computed: {
  113 + displayButtons() {
  114 + const s = this.form && this.form.status || false
  115 + return [
  116 + { ...this.buttons[0], visible: s && this.$auth.hasPermi('procure-manage:foreign-trade:review') },
  117 + { ...this.buttons[1], visible: s === 'AUDIT' && this.$auth.hasPermi('procure-manage:foreign-trade:approve') },
  118 + { ...this.buttons[2], visible: this.$auth.hasPermi('procure-manage:foreign-trade:modify') },
  119 + { ...this.buttons[3], visible: this.$auth.hasPermi('procure-manage:foreign-trade:cancel') },
  120 + ]
  121 + },
  122 + companyNatureText() {
  123 + const v = this.form && this.form.companyNature != null ? String(this.form.companyNature) : ''
  124 + if (!v) return '-'
  125 + return getDicName('COMPANY_NATURE', v, this.dicOptions.COMPANY_NATURE) || v
  126 + },
  127 + auditStatusText() {
  128 + const v = this.form && this.form.status != null ? String(this.form.status) : ''
  129 + if (!v) return '-'
  130 + return getDicName('AUDIT_STATUS', v, this.dicOptions.AUDIT_STATUS) || v
  131 + },
  132 + purchaseDeptName() {
  133 + if (this.purchaseDept && this.purchaseDept.name != null) return String(this.purchaseDept.name)
  134 + const v = this.form && this.form.purchaseDepartmentName != null ? String(this.form.purchaseDepartmentName) : ''
  135 + return v || '-'
  136 + },
  137 + supplierCategoryName() {
  138 + const v = this.form && this.form.supplierCategory != null ? String(this.form.supplierCategory) : ''
  139 + const map = { A: 'A类供应商', B: 'B类供应商', C: 'C类供应商', D: 'D类供应商' }
  140 + return map[v] || (v ? v : '-')
  141 + },
  142 + supplierCategoryDesc() {
  143 + const v = this.form && this.form.supplierCategory != null ? String(this.form.supplierCategory) : ''
  144 + const map = {
  145 + A: '资信调查有担保函无资金风险、资料齐全,料质可控,价格较好,若出现质量、磅差问题可以索赔解决,进口倒挂时可协商延迟点价,可推迟发货,可试操作(前3个月每月操作量300-500吨);第一次计划货到厂验收结束后进行评审,正常后可以增量操作,要求每年评审一次;',
  146 + B: '资信调查无担保函,国外企业属国内企业控股,无资金风险、资料齐全,价格较好,料质可控,若出现质量、磅差问题可以索赔解决(前3个月每月操作量200-400吨),第一次货到厂验收合格后可增量操作;操作正常每年评审一次;',
  147 + C: '资信调查无担保函,资料齐全,料质可控,价格一般,出现质量、磅差问题可以索赔解决,可试单限量操作(前3个月每月操作量100-200吨),第一次货到厂验收合格后可增量操作,新开发供应商首年操作按每半年评审一次,操作正常则次年调整为每年评审一次;若出现索赔问题不及时解决可中止后续开信用证和中止到港货物的DP/TT付款,且立即暂停业务操作。',
  148 + D: '资信调查无担保函,通过委托第三方机构调查无风险,虽然资料不齐全,但料质可控,价格略高,出现质量、磅差问题索赔解决有难度,一单一议,D类供应商第一次货到厂验收、付款、退款或者索赔正常后,可继续操作逐步增量(每月操作量100-200吨),每半年评审一次,操作正常到则次年调整为每年评审一次;若出现索赔问题不及时解决可终止后续到港货物的付款,且立即停止业务操作。'
  149 + }
  150 + return map[v] || '-'
  151 + },
  152 + reviewHint() {
  153 + const d = this.parseDateOnly(this.form && this.form.nextReviewTime)
  154 + if (!d) return ''
  155 + const now = new Date()
  156 + const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  157 + const diffDays = Math.floor((d.getTime() - today.getTime()) / (24 * 60 * 60 * 1000))
  158 + if (diffDays < 0) return '已到评审时间'
  159 + if (diffDays <= 15) return `距评审还有${diffDays}天`
  160 + return ''
  161 + }
  162 + },
  163 + created() {
  164 + this.loadDicData()
  165 + this.loadPurchaseDeptOptions()
  166 + },
  167 + onShow() {
  168 + const options = (this.$route && this.$route.query) ? this.$route.query : {}
  169 + const id = options && options.id ? String(options.id) : ''
  170 + this.id = id
  171 + this.loadDetail()
  172 + },
  173 + methods: {
  174 + async loadDicData() {
  175 + try {
  176 + const results = await getDicByCodes(['AUDIT_STATUS', 'COMPANY_NATURE'])
  177 + this.dicOptions.AUDIT_STATUS = (results.AUDIT_STATUS && results.AUDIT_STATUS.data) || []
  178 + this.dicOptions.COMPANY_NATURE = (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || []
  179 + } catch (e) {
  180 + this.dicOptions.AUDIT_STATUS = []
  181 + this.dicOptions.COMPANY_NATURE = []
  182 + }
  183 + },
  184 + async loadPurchaseDeptOptions() {
  185 + try {
  186 + const res = await getPurchaseDeptApi()
  187 + const data = (res && res.data) ? res.data : {}
  188 + this.purchaseDept = data && typeof data === 'object' ? data : null
  189 + } catch (e) {
  190 + this.purchaseDept = null
  191 + }
  192 + },
  193 + handleButtonClick(btn) {
  194 + if (!btn || btn.disabled) return
  195 + if (typeof btn.onClick === 'function') return btn.onClick(this.form, btn.params)
  196 + const e = btn.event || ''
  197 + if (e === 'audit') return this.onAudit(btn && btn.params)
  198 + if (e === 'auditDetail') return this.onAuditDetail(btn && btn.params)
  199 + if (e === 'edit') return this.onEdit(btn && btn.params)
  200 + if (e === 'cancel') return this.onCancel(btn && btn.params)
  201 + },
  202 + onAudit() {
  203 + const id = this.id || (this.form && this.form.id) || ''
  204 + if (!id) return
  205 + const CACHE_KEY = 'sourceBusinessId'
  206 + const TYPE = 'contractType'
  207 + uni.setStorageSync(TYPE, 'CUSTOMER_CREDIT_OUT')
  208 + uni.setStorageSync(CACHE_KEY, id)
  209 + uni.navigateTo({ url: '/pages/flow/audit' })
  210 + },
  211 + onAuditDetail() {
  212 + const id = this.id || (this.form && this.form.id) || ''
  213 + if (!id) return
  214 + const CACHE_KEY = 'sourceBusinessId'
  215 + const TYPE = 'contractType'
  216 + uni.setStorageSync(TYPE, 'CUSTOMER_CREDIT_OUT')
  217 + uni.setStorageSync(CACHE_KEY, id)
  218 + uni.navigateTo({ url: '/pages/flow/audit_detail' })
  219 + },
  220 + onEdit() {
  221 + uni.navigateTo({ url: '/pages/foreign_trade/modify?id=' + this.id })
  222 + },
  223 + onCancel() {
  224 + const id = this.id || (this.form && this.form.id) || ''
  225 + if (!id) return
  226 + uni.showModal({
  227 + title: '系统提示',
  228 + content: '是否确定取消该流程?',
  229 + confirmText: '确定',
  230 + cancelText: '取消',
  231 + success: (res) => {
  232 + if (res && res.confirm) {
  233 + foreignTradeCreditCancelApi(id).then(() => {
  234 + uni.showToast({ title: '已取消', icon: 'none' })
  235 + try { uni.setStorageSync('FOREIGN_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  236 + setTimeout(() => { uni.redirectTo({ url: '/pages/foreign_trade/index' }) }, 300)
  237 + }).catch((e) => {
  238 + uni.showToast({ title: (e && e.msg) || '取消失败', icon: 'none' })
  239 + })
  240 + }
  241 + }
  242 + })
  243 + },
  244 + safeText(v) {
  245 + const s = v == null ? '' : String(v)
  246 + return s.trim() ? s : '-'
  247 + },
  248 + parseDateOnly(v) {
  249 + const s = v == null ? '' : String(v).trim()
  250 + if (!s) return null
  251 + const d = new Date(s.length >= 10 ? s.slice(0, 10) : s)
  252 + if (!Number.isFinite(d.getTime())) return null
  253 + return new Date(d.getFullYear(), d.getMonth(), d.getDate())
  254 + },
  255 + async loadDetail() {
  256 + if (!this.id) return
  257 + this.loading = true
  258 + try {
  259 + const res = await foreignTradeCreditGetApi(this.id)
  260 + const data = (res && res.data) ? res.data : {}
  261 + this.form = data
  262 + } catch (e) {
  263 + this.form = {}
  264 + uni.showToast({ title: '详情加载失败', icon: 'none' })
  265 + } finally {
  266 + this.loading = false
  267 + }
  268 + },
  269 + }
  270 +}
  271 +</script>
  272 +
  273 +<style lang="scss" scoped>
  274 +.page {
  275 + display: flex;
  276 + flex-direction: column;
  277 + height: 100%;
  278 +}
  279 +
  280 +.scroll {
  281 + flex: 1;
  282 + padding: 8rpx 0 144rpx;
  283 +}
  284 +
  285 +.detail-page {
  286 + background: #f3f3f3;
  287 +}
  288 +
  289 +.title-header {
  290 + display: flex;
  291 + align-items: center;
  292 + padding: 24rpx 32rpx 12rpx;
  293 + background-color: #ffffff;
  294 +
  295 + .title-header_icon {
  296 + width: 36rpx;
  297 + height: 36rpx;
  298 + margin-right: 12rpx;
  299 + }
  300 +
  301 + span {
  302 + font-size: 34rpx;
  303 + font-weight: 600;
  304 + color: rgba(0, 0, 0, 0.9);
  305 + }
  306 +}
  307 +
  308 +.section {
  309 + padding: 32rpx;
  310 + background: #fff;
  311 + margin-bottom: 20rpx;
  312 +}
  313 +
  314 +.row {
  315 + display: flex;
  316 + margin-bottom: 28rpx;
  317 +
  318 + &:last-child {
  319 + margin-bottom: 0;
  320 + }
  321 +
  322 + &.company {
  323 + font-size: 36rpx;
  324 + font-weight: 600;
  325 + color: rgba(0, 0, 0, 0.9);
  326 + padding-top: 8rpx;
  327 + line-height: 50rpx;
  328 + }
  329 +
  330 + .label {
  331 + max-width: 420rpx;
  332 + margin-right: 20rpx;
  333 + line-height: 32rpx;
  334 + font-size: 28rpx;
  335 + color: rgba(0, 0, 0, 0.6);
  336 + }
  337 +
  338 + .value {
  339 + flex: 1;
  340 + line-height: 32rpx;
  341 + font-size: 28rpx;
  342 + color: rgba(0, 0, 0, 0.9);
  343 + text-align: right;
  344 + word-break: break-all;
  345 +
  346 + &.pre {
  347 + white-space: pre-wrap;
  348 + }
  349 + }
  350 +}
  351 +
  352 +.hint {
  353 + margin-top: 12rpx;
  354 + font-size: 26rpx;
  355 + color: #D54941;
  356 + text-align: right;
  357 +}
  358 +</style>
  359 +
  1 +<template>
  2 + <view class="detail-page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="section">
  5 + <text class="row company">{{ safeText(form.unitName) }}</text>
  6 + <view class="row"><text class="label">公司性质</text><text class="value">{{ safeText(companyNatureText) }}</text></view>
  7 + <view class="row"><text class="label">法人代表</text><text class="value">{{ safeText(form.legalRepresentative) }}</text></view>
  8 + <view class="row"><text class="label">电话及传真</text><text class="value">{{ safeText(form.phoneAndFax) }}</text></view>
  9 + <view class="row"><text class="label">注册证书号</text><text class="value">{{ safeText(form.registrationCertificateNo) }}</text></view>
  10 + <view class="row"><text class="label">地址</text><text class="value">{{ safeText(form.address) }}</text></view>
  11 + <view class="row"><text class="label">国内业务负责人</text><text class="value">{{ safeText(form.domesticBusinessPrincipal) }}</text></view>
  12 + <view class="row"><text class="label">负责人身份证/护照号</text><text class="value">{{ safeText(form.principalCertificateNo) }}</text></view>
  13 + <view class="row"><text class="label">成立时间及货场规模</text><text class="value pre">{{ safeText(form.establishedTimeAndYardScale) }}</text></view>
  14 + <view class="row"><text class="label">经营品种、规模</text><text class="value pre">{{ safeText(form.overallBusinessVarietiesScale) }}</text></view>
  15 + <view class="row"><text class="label">出口到国内时间</text><text class="value">{{ safeText(form.exportToDomesticTime) }}</text></view>
  16 + <view class="row"><text class="label">出口规模、品种</text><text class="value pre">{{ safeText(form.exportToDomesticScaleVarieties) }}</text></view>
  17 + <view class="row"><text class="label">与国内合作企业</text><text class="value pre">{{ safeText(form.cooperatingDomesticCompanies) }}</text></view>
  18 + <view class="row"><text class="label">合作效果</text><text class="value pre">{{ safeText(form.cooperationEffect) }}</text></view>
  19 + <view class="row"><text class="label">供应商考察</text><text class="value pre">{{ safeText(form.supplierInspection) }}</text></view>
  20 + <view class="row"><text class="label">销售代表办公地考察</text><text class="value pre">{{ safeText(form.domesticSalesOfficeInspection) }}</text></view>
  21 + <view class="row"><text class="label">有无担保函</text><text class="value">{{ safeText(form.guaranteeLetter) }}</text></view>
  22 + <view class="row"><text class="label">合同纠纷</text><text class="value pre">{{ safeText(form.contractDispute) }}</text></view>
  23 + <view class="row"><text class="label">保险、运输方式</text><text class="value">{{ safeText(form.insuranceTransportMode) }}</text></view>
  24 + <view class="row"><text class="label">滞箱滞报费用</text><text class="value">{{ safeText(form.detentionDemurrageFee) }}</text></view>
  25 + <view class="row"><text class="label">操作品种</text><text class="value">{{ safeText(form.operationVariety) }}</text></view>
  26 + <view class="row"><text class="label">操作规模</text><text class="value">{{ safeText(form.operationScale) }}</text></view>
  27 + <view class="row"><text class="label">定价模式</text><text class="value">{{ safeText(form.pricingMode) }}</text></view>
  28 + <view class="row"><text class="label">结算方式</text><text class="value">{{ safeText(form.settlementMethod) }}</text></view>
  29 + <view class="row"><text class="label">磅差约定</text><text class="value">{{ safeText(form.weightDifferenceAgreement) }}</text></view>
  30 + <view class="row"><text class="label">质量标准</text><text class="value">{{ safeText(form.qualityStandard) }}</text></view>
  31 + <view class="row"><text class="label">供应商分类</text><text class="value">{{ safeText(supplierCategoryName) }}</text></view>
  32 + </view>
  33 +
  34 + <view class="title-header">
  35 + <image class="title-header_icon" src="/static/images/title.png" />
  36 + <span>操作方案</span>
  37 + </view>
  38 + <view class="section">
  39 + <view class="row"><text class="label">操作时间</text><text class="value">{{ safeText(form.schemeOperationTime) }}</text></view>
  40 + <view class="row"><text class="label">操作模式</text><text class="value">{{ safeText(form.schemeOperationMode) }}</text></view>
  41 + <view class="row"><text class="label">操作品种</text><text class="value">{{ safeText(form.schemeOperationVariety) }}</text></view>
  42 + <view class="row"><text class="label">操作数量</text><text class="value">{{ safeText(form.schemeOperationQuantity) }}</text></view>
  43 + <view class="row"><text class="label">发货要求</text><text class="value pre">{{ safeText(form.shippingRequirement) }}</text></view>
  44 + <view class="row"><text class="label">付款方式</text><text class="value">{{ safeText(form.paymentMethod) }}</text></view>
  45 + <view class="row"><text class="label">下次评审时间</text><text class="value">{{ safeText(form.nextReviewTime) }}</text></view>
  46 + <view class="row"><text class="label">评审部门</text><text class="value">{{ safeText(form.reviewDepartment) }}</text></view>
  47 + <view class="row"><text class="label">资信调查人</text><text class="value">{{ safeText(form.investigatorName) }}</text></view>
  48 + <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(purchaseDeptName) }}</text></view>
  49 + </view>
  50 + </scroll-view>
  51 + </view>
  52 +</template>
  53 +
  54 +<script>
  55 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  56 +import { foreignTradeCreditGetExamineByIdApi, getPurchaseDeptApi } from '@/api/procure-manage/foreignTradeCredit.js'
  57 +
  58 +export default {
  59 + name: 'ForeignTradeCreditViewer',
  60 + props: { id: { type: [String, Number], default: '' } },
  61 + data() {
  62 + return {
  63 + form: {},
  64 + dicOptions: {
  65 + COMPANY_NATURE: []
  66 + },
  67 + purchaseDept: null
  68 + }
  69 + },
  70 + computed: {
  71 + companyNatureText() {
  72 + const v = this.form && this.form.companyNature != null ? String(this.form.companyNature) : ''
  73 + if (!v) return '-'
  74 + return getDicName('COMPANY_NATURE', v, this.dicOptions.COMPANY_NATURE) || v
  75 + },
  76 + supplierCategoryName() {
  77 + const v = this.form && this.form.supplierCategory != null ? String(this.form.supplierCategory) : ''
  78 + const map = { A: 'A类供应商', B: 'B类供应商', C: 'C类供应商', D: 'D类供应商' }
  79 + return map[v] || (v ? v : '-')
  80 + },
  81 + purchaseDeptName() {
  82 + if (this.purchaseDept && this.purchaseDept.name != null) return String(this.purchaseDept.name)
  83 + const v = this.form && this.form.purchaseDepartmentName != null ? String(this.form.purchaseDepartmentName) : ''
  84 + return v || '-'
  85 + }
  86 + },
  87 + created() {
  88 + this.loadDicData()
  89 + this.loadPurchaseDeptOptions()
  90 + },
  91 + watch: {
  92 + id: {
  93 + immediate: true,
  94 + handler(val) {
  95 + const v = (val !== undefined && val !== null) ? String(val) : ''
  96 + if (v) this.loadDetail(v)
  97 + }
  98 + }
  99 + },
  100 + methods: {
  101 + async loadDicData() {
  102 + try {
  103 + const results = await getDicByCodes(['COMPANY_NATURE'])
  104 + this.dicOptions.COMPANY_NATURE = (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || []
  105 + } catch (e) {
  106 + this.dicOptions.COMPANY_NATURE = []
  107 + }
  108 + },
  109 + async loadPurchaseDeptOptions() {
  110 + try {
  111 + const res = await getPurchaseDeptApi()
  112 + const data = (res && res.data) ? res.data : {}
  113 + this.purchaseDept = data && typeof data === 'object' ? data : null
  114 + } catch (e) {
  115 + this.purchaseDept = null
  116 + }
  117 + },
  118 + safeText(v) {
  119 + const s = v == null ? '' : String(v)
  120 + return s.trim() ? s : '-'
  121 + },
  122 + async loadDetail(id) {
  123 + try {
  124 + const res = await foreignTradeCreditGetExamineByIdApi(id)
  125 + this.form = (res && res.data) ? res.data : {}
  126 + } catch (e) {
  127 + this.form = {}
  128 + }
  129 + }
  130 + }
  131 +}
  132 +</script>
  133 +
  134 +<style lang="scss" scoped>
  135 +.detail-page {
  136 + background: #f3f3f3;
  137 +}
  138 +
  139 +.scroll {
  140 + flex: 1;
  141 + padding: 8rpx 0 144rpx;
  142 +}
  143 +
  144 +.title-header {
  145 + display: flex;
  146 + align-items: center;
  147 + padding: 24rpx 32rpx 12rpx;
  148 + background-color: #ffffff;
  149 +
  150 + .title-header_icon {
  151 + width: 36rpx;
  152 + height: 36rpx;
  153 + margin-right: 12rpx;
  154 + }
  155 +
  156 + span {
  157 + font-size: 34rpx;
  158 + font-weight: 600;
  159 + color: rgba(0, 0, 0, 0.9);
  160 + }
  161 +}
  162 +
  163 +.section {
  164 + padding: 32rpx;
  165 + background: #fff;
  166 + margin-bottom: 20rpx;
  167 +}
  168 +
  169 +.row {
  170 + display: flex;
  171 + margin-bottom: 28rpx;
  172 +
  173 + &:last-child {
  174 + margin-bottom: 0;
  175 + }
  176 +
  177 + &.company {
  178 + font-size: 36rpx;
  179 + font-weight: 600;
  180 + color: rgba(0, 0, 0, 0.9);
  181 + padding-top: 8rpx;
  182 + line-height: 50rpx;
  183 + }
  184 +
  185 + .label {
  186 + max-width: 420rpx;
  187 + margin-right: 20rpx;
  188 + line-height: 32rpx;
  189 + font-size: 28rpx;
  190 + color: rgba(0, 0, 0, 0.6);
  191 + }
  192 +
  193 + .value {
  194 + flex: 1;
  195 + line-height: 32rpx;
  196 + font-size: 28rpx;
  197 + color: rgba(0, 0, 0, 0.9);
  198 + text-align: right;
  199 + word-break: break-all;
  200 +
  201 + &.pre {
  202 + white-space: pre-wrap;
  203 + }
  204 + }
  205 +}
  206 +</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.unitName || '-' }}</text>
  22 + <text :class="['status', `status_${item.status}`]">{{ getAuditStatusText(item.status) }}</text>
  23 + </view>
  24 + <view class="info-row">
  25 + <text>公司性质</text><text>{{ getCompanyNatureText(item.companyNature) }}</text>
  26 + </view>
  27 + <view class="info-row">
  28 + <text>法人代表</text><text>{{ item.legalRepresentative || '-' }}</text>
  29 + </view>
  30 + <view class="info-row">
  31 + <text>下次评审时间</text><text>{{ formatDateOnly(item.nextReviewTime) }}</text>
  32 + </view>
  33 + <view class="info-row">
  34 + <text>登记日期</text><text>{{ formatDateOnly(item.createTime) }}</text>
  35 + </view>
  36 + <view v-if="reviewHint(item)" class="review-hint">{{ reviewHint(item) }}</view>
  37 + </view>
  38 + </template>
  39 + </card-list>
  40 + </view>
  41 +
  42 + <filter-modal :visible.sync="filterVisible" :value.sync="filterForm" title="筛选" @reset="onFilterReset"
  43 + @confirm="onFilterConfirm">
  44 + <template v-slot="{ model }">
  45 + <view class="filter-form">
  46 + <view class="form-item">
  47 + <view class="label">审核状态</view>
  48 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  49 + v-model="model.status" @change="onAuditStatusChange" :localdata="statusOptions" />
  50 + </view>
  51 + <view class="form-item">
  52 + <view class="label">登记日期</view>
  53 + <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
  54 + </view>
  55 + </view>
  56 + </template>
  57 + </filter-modal>
  58 + </view>
  59 +</template>
  60 +
  61 +<script>
  62 +import CardList from '@/components/card/index.vue'
  63 +import FilterModal from '@/components/filter/index.vue'
  64 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  65 +import { foreignTradeCreditQueryApi } from '@/api/procure-manage/foreignTradeCredit.js'
  66 +
  67 +export default {
  68 + name: 'ForeignTradeList',
  69 + components: { CardList, FilterModal },
  70 + data() {
  71 + return {
  72 + searchKeyword: '',
  73 + searchKeywordDebounced: '',
  74 + searchDebounceTimer: null,
  75 + query: {
  76 + unitName: '',
  77 + status: '',
  78 + dateRange: []
  79 + },
  80 + extraParams: {},
  81 + currentItems: [],
  82 + filterVisible: false,
  83 + filterForm: {
  84 + status: '',
  85 + dateRange: []
  86 + },
  87 + statusOptions: [
  88 + { value: '', text: '全部' }
  89 + ],
  90 + dicOptions: {
  91 + AUDIT_STATUS: [],
  92 + COMPANY_NATURE: []
  93 + },
  94 + }
  95 + },
  96 + watch: {
  97 + searchKeywordDebounced(v) {
  98 + this.query = { ...this.query, unitName: v || '' }
  99 + }
  100 + },
  101 + created() {
  102 + this.loadDicData()
  103 + },
  104 + onShow() {
  105 + let needRefresh = ''
  106 + try { needRefresh = uni.getStorageSync('FOREIGN_TRADE_LIST_NEED_REFRESH') } catch (e) {}
  107 + if (!needRefresh) return
  108 + try { uni.removeStorageSync('FOREIGN_TRADE_LIST_NEED_REFRESH') } catch (e) {}
  109 + if (this.$refs && this.$refs.cardRef && this.$refs.cardRef.reload) {
  110 + this.$refs.cardRef.reload()
  111 + }
  112 + },
  113 + onReachBottom() {
  114 + if (this.$refs && this.$refs.cardRef && this.$refs.cardRef.onLoadMore) {
  115 + this.$refs.cardRef.onLoadMore()
  116 + }
  117 + },
  118 + beforeDestroy() {
  119 + if (this.searchDebounceTimer) {
  120 + clearTimeout(this.searchDebounceTimer)
  121 + this.searchDebounceTimer = null
  122 + }
  123 + },
  124 + methods: {
  125 + async loadDicData() {
  126 + try {
  127 + const results = await getDicByCodes(['AUDIT_STATUS', 'COMPANY_NATURE'])
  128 + this.dicOptions.AUDIT_STATUS = (results.AUDIT_STATUS && results.AUDIT_STATUS.data) || []
  129 + this.dicOptions.COMPANY_NATURE = (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || []
  130 + const list = Array.isArray(this.dicOptions.AUDIT_STATUS) ? this.dicOptions.AUDIT_STATUS : []
  131 + this.statusOptions = [{ value: '', text: '全部' }].concat(
  132 + list.map(it => ({ value: it && it.code != null ? String(it.code) : '', text: it && it.name != null ? String(it.name) : '' })).filter(it => it.value)
  133 + )
  134 + } catch (e) {
  135 + this.dicOptions.AUDIT_STATUS = []
  136 + this.dicOptions.COMPANY_NATURE = []
  137 + this.statusOptions = [{ value: '', text: '全部' }]
  138 + }
  139 + },
  140 + formatDateOnly(v) {
  141 + const s = v == null ? '' : String(v).trim()
  142 + if (!s) return '-'
  143 + if (s.length >= 10) return s.slice(0, 10)
  144 + return s
  145 + },
  146 + parseDateOnly(v) {
  147 + const s = v == null ? '' : String(v).trim()
  148 + if (!s) return null
  149 + const d = new Date(s.length >= 10 ? s.slice(0, 10) : s)
  150 + if (!Number.isFinite(d.getTime())) return null
  151 + return new Date(d.getFullYear(), d.getMonth(), d.getDate())
  152 + },
  153 + reviewHint(item) {
  154 + const nextReviewTime = item && item.nextReviewTime != null ? String(item.nextReviewTime) : ''
  155 + const d = this.parseDateOnly(nextReviewTime)
  156 + if (!d) return ''
  157 + const now = new Date()
  158 + const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  159 + const diffDays = Math.floor((d.getTime() - today.getTime()) / (24 * 60 * 60 * 1000))
  160 + if (diffDays < 0) return '已到评审时间'
  161 + if (diffDays <= 15) return `距评审还有${diffDays}天`
  162 + return ''
  163 + },
  164 + onAdd() {
  165 + uni.navigateTo({ url: '/pages/foreign_trade/add' })
  166 + },
  167 + onCardLoaded({ items }) {
  168 + this.currentItems = items
  169 + },
  170 + onCardError() {
  171 + uni.showToast({ title: '列表加载失败', icon: 'none' })
  172 + },
  173 + onSearchInput() {
  174 + if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer)
  175 + this.searchDebounceTimer = setTimeout(() => {
  176 + this.searchKeywordDebounced = this.searchKeyword
  177 + this.searchDebounceTimer = null
  178 + }, 1200)
  179 + },
  180 + search(e) {
  181 + const val = e && e.value != null ? e.value : this.searchKeyword
  182 + this.searchKeyword = val
  183 + this.searchKeywordDebounced = val
  184 + },
  185 + openFilter() {
  186 + this.filterForm = {
  187 + status: this.query.status || '',
  188 + dateRange: Array.isArray(this.query.dateRange) ? this.query.dateRange.slice(0) : []
  189 + }
  190 + this.filterVisible = true
  191 + },
  192 + onFilterReset(payload) {
  193 + this.filterForm = payload
  194 + },
  195 + onFilterConfirm(payload) {
  196 + this.query = {
  197 + unitName: this.query.unitName || '',
  198 + status: payload.status || '',
  199 + dateRange: Array.isArray(payload.dateRange) ? payload.dateRange : []
  200 + }
  201 + },
  202 + onAuditStatusChange(e) {
  203 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  204 + this.filterForm.status = raw
  205 + },
  206 + getAuditStatusText(status) {
  207 + const v = status == null ? '' : String(status)
  208 + if (!v) return '-'
  209 + return getDicName('AUDIT_STATUS', v, this.dicOptions.AUDIT_STATUS) || v
  210 + },
  211 + getCompanyNatureText(v) {
  212 + const s = v == null ? '' : String(v).trim()
  213 + if (!s) return '-'
  214 + return getDicName('COMPANY_NATURE', s, this.dicOptions.COMPANY_NATURE) || s
  215 + },
  216 + fetchList({ pageIndex, pageSize, query }) {
  217 + const q = query || {}
  218 + const range = Array.isArray(q.dateRange) ? q.dateRange : []
  219 + const params = {
  220 + pageIndex,
  221 + pageSize,
  222 + unitName: q.unitName || '',
  223 + status: q.status || '',
  224 + createDateStart: (range && range.length === 2) ? range[0] : '',
  225 + createDateEnd: (range && range.length === 2) ? range[1] : ''
  226 + }
  227 + return foreignTradeCreditQueryApi(params).then(res => {
  228 + const _data = res && res.data ? res.data : {}
  229 + let records = _data.datas || _data.list || _data.records || []
  230 + const totalCount = _data.totalCount || _data.count || 0
  231 + const hasNext = _data.hasNext || false
  232 + records = records.map(it => ({ ...it }))
  233 + return { records, totalCount, hasNext }
  234 + }).catch(() => {
  235 + this.onCardError()
  236 + return { records: [], totalCount: 0, hasNext: false }
  237 + })
  238 + },
  239 + onCardClick(item) {
  240 + uni.navigateTo({ url: '/pages/foreign_trade/detail?id=' + item.id })
  241 + },
  242 + }
  243 +}
  244 +</script>
  245 +
  246 +<style lang="scss" scoped>
  247 +.page {
  248 + display: flex;
  249 + flex-direction: column;
  250 + height: 100vh;
  251 +}
  252 +
  253 +.dev-list-fixed {
  254 + position: fixed;
  255 + top: 96rpx;
  256 + left: 0;
  257 + right: 0;
  258 + z-index: 2;
  259 + background: #fff;
  260 +
  261 + .search-row {
  262 + display: flex;
  263 + align-items: center;
  264 + padding: 16rpx 32rpx;
  265 +
  266 + .uni-searchbar {
  267 + padding: 0;
  268 + flex: 1;
  269 + }
  270 +
  271 + .tool-icons {
  272 + display: flex;
  273 +
  274 + .tool-icon {
  275 + width: 48rpx;
  276 + height: 48rpx;
  277 + display: block;
  278 + margin-left: 32rpx;
  279 + }
  280 + }
  281 + }
  282 +}
  283 +
  284 +::v-deep .uni-searchbar__box {
  285 + height: 80rpx !important;
  286 + justify-content: start;
  287 +
  288 + .uni-searchbar__box-search-input {
  289 + font-size: 32rpx !important;
  290 + }
  291 +}
  292 +
  293 +.list-box {
  294 + flex: 1;
  295 + padding-top: 140rpx;
  296 +
  297 + .card {
  298 + position: relative;
  299 + }
  300 +
  301 + .card-header {
  302 + margin-bottom: 28rpx;
  303 + position: relative;
  304 +
  305 + .title {
  306 + font-size: 36rpx;
  307 + font-weight: 600;
  308 + line-height: 50rpx;
  309 + color: rgba(0, 0, 0, 0.9);
  310 + width: 578rpx;
  311 + }
  312 +
  313 + .status {
  314 + position: absolute;
  315 + top: -32rpx;
  316 + right: -12rpx;
  317 + height: 48rpx;
  318 + line-height: 48rpx;
  319 + font-weight: 600;
  320 + color: #fff;
  321 + font-size: 24rpx;
  322 + padding: 0 14rpx;
  323 + border-radius: 6rpx;
  324 +
  325 + &.status_AUDIT {
  326 + background: $theme-primary;
  327 + }
  328 +
  329 + &.status_PASS {
  330 + background: #2BA471;
  331 + }
  332 +
  333 + &.status_REFUSE {
  334 + background: #D54941;
  335 + }
  336 +
  337 + &.status_CANCEL {
  338 + background: #E7E7E7;
  339 + color: rgba(0, 0, 0, 0.9);
  340 + }
  341 + }
  342 + }
  343 +
  344 + .info-row {
  345 + display: flex;
  346 + align-items: center;
  347 + color: rgba(0, 0, 0, 0.6);
  348 + font-size: 28rpx;
  349 + margin-bottom: 24rpx;
  350 + height: 32rpx;
  351 +
  352 + &:last-child {
  353 + margin-bottom: 0;
  354 + }
  355 +
  356 + text {
  357 + width: 50%;
  358 +
  359 + &:last-child {
  360 + color: rgba(0, 0, 0, 0.9);
  361 + width: 50%;
  362 + }
  363 + }
  364 + }
  365 +
  366 + .review-hint {
  367 + margin-top: 12rpx;
  368 + font-size: 26rpx;
  369 + color: #D54941;
  370 + }
  371 +}
  372 +
  373 +.filter-form {
  374 + .form-item {
  375 + margin-bottom: 24rpx;
  376 + }
  377 +
  378 + .label {
  379 + margin-bottom: 20rpx;
  380 + color: rgba(0, 0, 0, 0.9);
  381 + height: 44rpx;
  382 + line-height: 44rpx;
  383 + font-size: 30rpx;
  384 + }
  385 +}
  386 +</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.unitName" placeholder="请输入" :inputBorder="false" />
  13 + </template>
  14 + </uni-list-item>
  15 +
  16 + <uni-list-item class="select-item" :class="form.companyNature ? 'is-filled' : 'is-empty'" clickable
  17 + @click="openSheet('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 +
  23 + <uni-list-item title="法人代表">
  24 + <template v-slot:footer>
  25 + <uni-easyinput v-model="form.legalRepresentative" placeholder="请输入" :inputBorder="false" />
  26 + </template>
  27 + </uni-list-item>
  28 +
  29 + <uni-list-item title="电话及传真">
  30 + <template v-slot:footer>
  31 + <uni-easyinput v-model="form.phoneAndFax" placeholder="请输入" :inputBorder="false" />
  32 + </template>
  33 + </uni-list-item>
  34 +
  35 + <uni-list-item title="注册证书号">
  36 + <template v-slot:footer>
  37 + <uni-easyinput v-model="form.registrationCertificateNo" placeholder="请输入" :inputBorder="false" />
  38 + </template>
  39 + </uni-list-item>
  40 +
  41 + <uni-list-item title="地址">
  42 + <template v-slot:footer>
  43 + <uni-easyinput v-model="form.address" placeholder="请输入" :inputBorder="false" />
  44 + </template>
  45 + </uni-list-item>
  46 +
  47 + <uni-list-item title="国内业务负责人">
  48 + <template v-slot:footer>
  49 + <uni-easyinput v-model="form.domesticBusinessPrincipal" placeholder="请输入" :inputBorder="false" />
  50 + </template>
  51 + </uni-list-item>
  52 +
  53 + <uni-list-item title="负责人身份证/护照号">
  54 + <template v-slot:footer>
  55 + <uni-easyinput v-model="form.principalCertificateNo" placeholder="请输入" :inputBorder="false" />
  56 + </template>
  57 + </uni-list-item>
  58 +
  59 + <uni-list-item title="成立时间及货场规模">
  60 + <template v-slot:footer>
  61 + <uni-easyinput type="textarea" v-model="form.establishedTimeAndYardScale" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  62 + </template>
  63 + </uni-list-item>
  64 +
  65 + <uni-list-item title="经营品种、规模">
  66 + <template v-slot:footer>
  67 + <uni-easyinput type="textarea" v-model="form.overallBusinessVarietiesScale" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  68 + </template>
  69 + </uni-list-item>
  70 +
  71 + <uni-list-item title="出口到国内时间">
  72 + <template v-slot:footer>
  73 + <uni-easyinput v-model="form.exportToDomesticTime" placeholder="请输入" :inputBorder="false" />
  74 + </template>
  75 + </uni-list-item>
  76 +
  77 + <uni-list-item title="出口规模、品种">
  78 + <template v-slot:footer>
  79 + <uni-easyinput type="textarea" v-model="form.exportToDomesticScaleVarieties" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  80 + </template>
  81 + </uni-list-item>
  82 +
  83 + <uni-list-item title="与国内合作企业">
  84 + <template v-slot:footer>
  85 + <uni-easyinput type="textarea" v-model="form.cooperatingDomesticCompanies" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  86 + </template>
  87 + </uni-list-item>
  88 +
  89 + <uni-list-item title="合作效果">
  90 + <template v-slot:footer>
  91 + <uni-easyinput type="textarea" v-model="form.cooperationEffect" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  92 + </template>
  93 + </uni-list-item>
  94 +
  95 + <uni-list-item title="供应商考察">
  96 + <template v-slot:footer>
  97 + <uni-easyinput type="textarea" v-model="form.supplierInspection" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  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.domesticSalesOfficeInspection" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  104 + </template>
  105 + </uni-list-item>
  106 +
  107 + <uni-list-item title="有无担保函">
  108 + <template v-slot:footer>
  109 + <uni-easyinput v-model="form.guaranteeLetter" placeholder="请输入" :inputBorder="false" />
  110 + </template>
  111 + </uni-list-item>
  112 +
  113 + <uni-list-item title="合同纠纷">
  114 + <template v-slot:footer>
  115 + <uni-easyinput type="textarea" v-model="form.contractDispute" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  116 + </template>
  117 + </uni-list-item>
  118 +
  119 + <uni-list-item title="保险、运输方式">
  120 + <template v-slot:footer>
  121 + <uni-easyinput v-model="form.insuranceTransportMode" placeholder="请输入" :inputBorder="false" />
  122 + </template>
  123 + </uni-list-item>
  124 +
  125 + <uni-list-item title="滞箱滞报费用">
  126 + <template v-slot:footer>
  127 + <uni-easyinput v-model="form.detentionDemurrageFee" placeholder="请输入" :inputBorder="false" />
  128 + </template>
  129 + </uni-list-item>
  130 +
  131 + <uni-list-item title="操作品种">
  132 + <template v-slot:footer>
  133 + <uni-easyinput v-model="form.operationVariety" placeholder="请输入" :inputBorder="false" />
  134 + </template>
  135 + </uni-list-item>
  136 +
  137 + <uni-list-item title="操作规模">
  138 + <template v-slot:footer>
  139 + <uni-easyinput v-model="form.operationScale" placeholder="请输入" :inputBorder="false" />
  140 + </template>
  141 + </uni-list-item>
  142 +
  143 + <uni-list-item title="定价模式">
  144 + <template v-slot:footer>
  145 + <uni-easyinput v-model="form.pricingMode" placeholder="请输入" :inputBorder="false" />
  146 + </template>
  147 + </uni-list-item>
  148 +
  149 + <uni-list-item title="结算方式">
  150 + <template v-slot:footer>
  151 + <uni-easyinput v-model="form.settlementMethod" placeholder="请输入" :inputBorder="false" />
  152 + </template>
  153 + </uni-list-item>
  154 +
  155 + <uni-list-item title="磅差约定">
  156 + <template v-slot:footer>
  157 + <uni-easyinput v-model="form.weightDifferenceAgreement" placeholder="请输入" :inputBorder="false" />
  158 + </template>
  159 + </uni-list-item>
  160 +
  161 + <uni-list-item class="mgb10" title="质量标准">
  162 + <template v-slot:footer>
  163 + <uni-easyinput v-model="form.qualityStandard" placeholder="请输入" :inputBorder="false" />
  164 + </template>
  165 + </uni-list-item>
  166 +
  167 + <view class="title-header">
  168 + <image class="title-header_icon" src="/static/images/title.png" />
  169 + <span>供应商分类</span>
  170 + </view>
  171 +
  172 + <uni-list-item class="select-item" :class="form.supplierCategory ? 'is-filled' : 'is-empty'" clickable
  173 + @click="openSheet('supplierCategory')" :rightText="displayLabel('supplierCategory')" showArrow>
  174 + <template v-slot:body>
  175 + <view class="item-title"><text>供应商分类</text></view>
  176 + </template>
  177 + </uni-list-item>
  178 +
  179 + <uni-list-item v-if="form.supplierCategory" class="mgb10" title="分类说明">
  180 + <template v-slot:footer>
  181 + <uni-easyinput type="textarea" :value="supplierCategoryDesc" :inputBorder="false" disabled placeholder="选择供应商分类后自动显示" maxlength="2000" />
  182 + </template>
  183 + </uni-list-item>
  184 +
  185 + <view class="title-header">
  186 + <image class="title-header_icon" src="/static/images/title.png" />
  187 + <span>操作方案</span>
  188 + </view>
  189 +
  190 + <uni-list-item title="操作时间">
  191 + <template v-slot:footer>
  192 + <uni-easyinput v-model="form.schemeOperationTime" placeholder="请输入" :inputBorder="false" />
  193 + </template>
  194 + </uni-list-item>
  195 +
  196 + <uni-list-item title="操作模式">
  197 + <template v-slot:footer>
  198 + <uni-easyinput v-model="form.schemeOperationMode" placeholder="请输入" :inputBorder="false" />
  199 + </template>
  200 + </uni-list-item>
  201 +
  202 + <uni-list-item title="操作品种">
  203 + <template v-slot:footer>
  204 + <uni-easyinput v-model="form.schemeOperationVariety" placeholder="请输入" :inputBorder="false" />
  205 + </template>
  206 + </uni-list-item>
  207 +
  208 + <uni-list-item title="操作数量">
  209 + <template v-slot:footer>
  210 + <uni-easyinput v-model="form.schemeOperationQuantity" placeholder="请输入" :inputBorder="false" />
  211 + </template>
  212 + </uni-list-item>
  213 +
  214 + <uni-list-item title="发货要求">
  215 + <template v-slot:footer>
  216 + <uni-easyinput type="textarea" v-model="form.shippingRequirement" placeholder="请输入" :inputBorder="false" maxlength="2000" />
  217 + </template>
  218 + </uni-list-item>
  219 +
  220 + <uni-list-item title="付款方式">
  221 + <template v-slot:footer>
  222 + <uni-easyinput v-model="form.paymentMethod" placeholder="请输入" :inputBorder="false" />
  223 + </template>
  224 + </uni-list-item>
  225 +
  226 + <uni-list-item title="下次评审时间">
  227 + <template v-slot:footer>
  228 + <uni-datetime-picker type="date" v-model="form.nextReviewTime" />
  229 + </template>
  230 + </uni-list-item>
  231 +
  232 + <uni-list-item title="评审部门">
  233 + <template v-slot:footer>
  234 + <uni-easyinput v-model="form.reviewDepartment" placeholder="请输入" :inputBorder="false" />
  235 + </template>
  236 + </uni-list-item>
  237 +
  238 + <uni-list-item title="资信调查人">
  239 + <template v-slot:footer>
  240 + <uni-easyinput v-model="form.investigatorName" :inputBorder="false" disabled />
  241 + </template>
  242 + </uni-list-item>
  243 +
  244 + <uni-list-item class="mgb10" title="采购处">
  245 + <template v-slot:footer>
  246 + <uni-easyinput v-model="form.purchaseDepartmentName" :inputBorder="false" disabled />
  247 + </template>
  248 + </uni-list-item>
  249 + </uni-list>
  250 + </scroll-view>
  251 +
  252 + <view class="footer">
  253 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '保存中...' : '保存' }}</button>
  254 + </view>
  255 +
  256 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  257 + @confirm="onSheetConfirm" />
  258 + </view>
  259 +</template>
  260 +
  261 +<script>
  262 +import SingleSelectSheet from '@/components/single-select/index.vue'
  263 +import { getDicByCodes } from '@/utils/dic.js'
  264 +import { foreignTradeCreditGetApi, foreignTradeCreditSaveApi, getPurchaseDeptApi } from '@/api/procure-manage/foreignTradeCredit.js'
  265 +
  266 +export default {
  267 + name: 'ForeignTradeModify',
  268 + components: { SingleSelectSheet },
  269 + data() {
  270 + return {
  271 + id: '',
  272 + submitting: false,
  273 + loading: false,
  274 + supplierCategoryOptions: [
  275 + { label: 'A类供应商', value: 'A' },
  276 + { label: 'B类供应商', value: 'B' },
  277 + { label: 'C类供应商', value: 'C' },
  278 + { label: 'D类供应商', value: 'D' }
  279 + ],
  280 + companyNatureOptions: [],
  281 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  282 + form: {
  283 + id: '',
  284 + unitName: '',
  285 + companyNature: '',
  286 + companyNatureName: '',
  287 + legalRepresentative: '',
  288 + phoneAndFax: '',
  289 + registrationCertificateNo: '',
  290 + address: '',
  291 + domesticBusinessPrincipal: '',
  292 + principalCertificateNo: '',
  293 + establishedTimeAndYardScale: '',
  294 + overallBusinessVarietiesScale: '',
  295 + exportToDomesticTime: '',
  296 + exportToDomesticScaleVarieties: '',
  297 + cooperatingDomesticCompanies: '',
  298 + cooperationEffect: '',
  299 + supplierInspection: '',
  300 + domesticSalesOfficeInspection: '',
  301 + guaranteeLetter: '',
  302 + contractDispute: '',
  303 + insuranceTransportMode: '',
  304 + detentionDemurrageFee: '',
  305 + operationVariety: '',
  306 + operationScale: '',
  307 + pricingMode: '',
  308 + settlementMethod: '',
  309 + weightDifferenceAgreement: '',
  310 + qualityStandard: '',
  311 + supplierCategory: '',
  312 + schemeOperationTime: '',
  313 + schemeOperationMode: '',
  314 + schemeOperationVariety: '',
  315 + schemeOperationQuantity: '',
  316 + shippingRequirement: '',
  317 + paymentMethod: '',
  318 + nextReviewTime: '',
  319 + reviewDepartment: '',
  320 + investigatorId: '',
  321 + investigatorName: '',
  322 + purchaseDepartment: '',
  323 + purchaseDepartmentName: ''
  324 + }
  325 + }
  326 + },
  327 + computed: {
  328 + supplierCategoryDesc() {
  329 + const v = this.form && this.form.supplierCategory != null ? String(this.form.supplierCategory) : ''
  330 + const map = {
  331 + A: '资信调查有担保函无资金风险、资料齐全,料质可控,价格较好,若出现质量、磅差问题可以索赔解决,进口倒挂时可协商延迟点价,可推迟发货,可试操作(前3个月每月操作量300-500吨);第一次计划货到厂验收结束后进行评审,正常后可以增量操作,要求每年评审一次;',
  332 + B: '资信调查无担保函,国外企业属国内企业控股,无资金风险、资料齐全,价格较好,料质可控,若出现质量、磅差问题可以索赔解决(前3个月每月操作量200-400吨),第一次货到厂验收合格后可增量操作;操作正常每年评审一次;',
  333 + C: '资信调查无担保函,资料齐全,料质可控,价格一般,出现质量、磅差问题可以索赔解决,可试单限量操作(前3个月每月操作量100-200吨),第一次货到厂验收合格后可增量操作,新开发供应商首年操作按每半年评审一次,操作正常则次年调整为每年评审一次;若出现索赔问题不及时解决可中止后续开信用证和中止到港货物的DP/TT付款,且立即暂停业务操作。',
  334 + D: '资信调查无担保函,通过委托第三方机构调查无风险,虽然资料不齐全,但料质可控,价格略高,出现质量、磅差问题索赔解决有难度,一单一议,D类供应商第一次货到厂验收、付款、退款或者索赔正常后,可继续操作逐步增量(每月操作量100-200吨),每半年评审一次,操作正常到则次年调整为每年评审一次;若出现索赔问题不及时解决可终止后续到港货物的付款,且立即停止业务操作。'
  335 + }
  336 + return map[v] || ''
  337 + }
  338 + },
  339 + async onLoad(query) {
  340 + const id = (query && (query.id || query.code)) ? String(query.id || query.code) : ''
  341 + this.id = id
  342 + await this.loadDicData()
  343 + await this.loadPurchaseDeptOptions()
  344 + await this.loadDetail()
  345 + },
  346 + methods: {
  347 + async loadDicData() {
  348 + try {
  349 + const results = await getDicByCodes(['COMPANY_NATURE'])
  350 + const items = results && results.COMPANY_NATURE && results.COMPANY_NATURE.data ? results.COMPANY_NATURE.data : []
  351 + this.companyNatureOptions = (Array.isArray(items) ? items : []).map(it => ({
  352 + label: it && it.name != null ? String(it.name) : '',
  353 + value: it && it.code != null ? String(it.code) : ''
  354 + })).filter(it => it.value)
  355 + } catch (e) {
  356 + this.companyNatureOptions = []
  357 + }
  358 + },
  359 + async loadPurchaseDeptOptions() {
  360 + try {
  361 + const res = await getPurchaseDeptApi()
  362 + const data = (res && res.data) ? res.data : {}
  363 + this.form.purchaseDepartment = data && data.id != null ? String(data.id) : ''
  364 + this.form.purchaseDepartmentName = data && data.name != null ? String(data.name) : ''
  365 + } catch (e) {
  366 + this.form.purchaseDepartment = ''
  367 + this.form.purchaseDepartmentName = ''
  368 + }
  369 + },
  370 + displayLabel(field) {
  371 + const m = this.form || {}
  372 + const map = {
  373 + companyNatureName: '请选择',
  374 + supplierCategory: '请选择'
  375 + }
  376 + if (field === 'supplierCategory') {
  377 + const code = m.supplierCategory
  378 + const found = (this.supplierCategoryOptions || []).find(o => String(o.value) === String(code))
  379 + return found ? String(found.label || '') : map[field]
  380 + }
  381 + const v = m[field]
  382 + if (v != null && String(v).trim()) return String(v)
  383 + return map[field] || '请选择'
  384 + },
  385 + openSheet(field) {
  386 + const map = {
  387 + companyNature: { title: '公司性质', options: this.companyNatureOptions, valueField: 'companyNature', labelField: 'companyNatureName' },
  388 + supplierCategory: { title: '供应商分类', options: this.supplierCategoryOptions, valueField: 'supplierCategory', labelField: '' }
  389 + }
  390 + const cfg = map[field]
  391 + if (!cfg) return
  392 + const current = this.form[cfg.valueField]
  393 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  394 + this.sheet = {
  395 + ...this.sheet,
  396 + visible: true,
  397 + title: cfg.title,
  398 + options: cfg.options || [],
  399 + field,
  400 + value: match ? match.value : current
  401 + }
  402 + },
  403 + onSheetConfirm({ value, label }) {
  404 + const field = this.sheet.field
  405 + if (field === 'companyNature') this.form.companyNatureName = label
  406 + if (field === 'supplierCategory') {
  407 + this.form.supplierCategory = value
  408 + }
  409 + if (field === 'companyNature') this.form.companyNature = value
  410 + this.sheet.visible = false
  411 + },
  412 + async loadDetail() {
  413 + if (!this.id) return
  414 + this.loading = true
  415 + try {
  416 + const res = await foreignTradeCreditGetApi(this.id)
  417 + const data = (res && res.data) ? res.data : {}
  418 + this.form = { ...this.form, ...data, id: this.id }
  419 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  420 + if (!this.form.investigatorId) this.form.investigatorId = u && u.id ? String(u.id) : ''
  421 + if (!this.form.investigatorName) this.form.investigatorName = u && u.name ? String(u.name) : ''
  422 + if (!this.form.companyNatureName && this.form.companyNature) {
  423 + const found = (this.companyNatureOptions || []).find(o => String(o.value) === String(this.form.companyNature))
  424 + if (found) this.form.companyNatureName = String(found.label || '')
  425 + }
  426 + } catch (e) {
  427 + uni.showToast({ title: '详情加载失败', icon: 'none' })
  428 + } finally {
  429 + this.loading = false
  430 + }
  431 + },
  432 + validate() {
  433 + const requiredFields = [
  434 + { key: 'unitName', label: '单位名称' },
  435 + { key: 'companyNature', label: '公司性质' },
  436 + { key: 'legalRepresentative', label: '法人代表' },
  437 + { key: 'phoneAndFax', label: '电话及传真' },
  438 + { key: 'registrationCertificateNo', label: '注册证书号' },
  439 + { key: 'address', label: '地址' },
  440 + { key: 'domesticBusinessPrincipal', label: '国内业务负责人' },
  441 + { key: 'principalCertificateNo', label: '负责人身份证/护照号' },
  442 + { key: 'establishedTimeAndYardScale', label: '成立时间及货场规模' },
  443 + { key: 'overallBusinessVarietiesScale', label: '经营品种、规模' },
  444 + { key: 'exportToDomesticTime', label: '出口到国内时间' },
  445 + { key: 'exportToDomesticScaleVarieties', label: '出口规模、品种' },
  446 + { key: 'cooperatingDomesticCompanies', label: '与国内合作企业' },
  447 + { key: 'cooperationEffect', label: '合作效果' },
  448 + { key: 'supplierInspection', label: '供应商考察' },
  449 + { key: 'domesticSalesOfficeInspection', label: '销售代表办公地考察' },
  450 + { key: 'guaranteeLetter', label: '有无担保函' },
  451 + { key: 'contractDispute', label: '合同纠纷' },
  452 + { key: 'insuranceTransportMode', label: '保险、运输方式' },
  453 + { key: 'detentionDemurrageFee', label: '滞箱滞报费用' },
  454 + { key: 'operationVariety', label: '操作品种' },
  455 + { key: 'operationScale', label: '操作规模' },
  456 + { key: 'pricingMode', label: '定价模式' },
  457 + { key: 'settlementMethod', label: '结算方式' },
  458 + { key: 'weightDifferenceAgreement', label: '磅差约定' },
  459 + { key: 'qualityStandard', label: '质量标准' },
  460 + { key: 'supplierCategory', label: '供应商分类' },
  461 + { key: 'schemeOperationTime', label: '操作时间' },
  462 + { key: 'schemeOperationMode', label: '操作模式' },
  463 + { key: 'schemeOperationVariety', label: '操作品种' },
  464 + { key: 'schemeOperationQuantity', label: '操作数量' },
  465 + { key: 'shippingRequirement', label: '发货要求' },
  466 + { key: 'paymentMethod', label: '付款方式' },
  467 + { key: 'nextReviewTime', label: '下次评审时间' },
  468 + { key: 'reviewDepartment', label: '评审部门' },
  469 + { key: 'investigatorId', label: '资信调查人ID' },
  470 + { key: 'purchaseDepartment', label: '采购处' }
  471 + ]
  472 + for (let i = 0; i < requiredFields.length; i++) {
  473 + const f = requiredFields[i]
  474 + const v = this.form && this.form[f.key]
  475 + if (v == null || String(v).trim() === '') {
  476 + uni.showToast({ title: `${f.label}必填`, icon: 'none' })
  477 + return false
  478 + }
  479 + }
  480 + return true
  481 + },
  482 + buildPayload() {
  483 + return { ...this.form, id: this.id }
  484 + },
  485 + async onSubmit() {
  486 + if (this.submitting) return
  487 + if (!this.validate()) return
  488 + this.submitting = true
  489 + const payload = this.buildPayload()
  490 + try {
  491 + await foreignTradeCreditSaveApi(payload)
  492 + uni.showToast({ title: '保存成功', icon: 'success' })
  493 + try { uni.setStorageSync('FOREIGN_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  494 + setTimeout(() => { uni.navigateBack() }, 300)
  495 + } catch (e) {
  496 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  497 + } finally {
  498 + this.submitting = false
  499 + }
  500 + },
  501 + }
  502 +}
  503 +</script>
  504 +
  505 +<style lang="scss" scoped>
  506 +.page {
  507 + display: flex;
  508 + flex-direction: column;
  509 + height: 100%;
  510 +}
  511 +
  512 +.scroll {
  513 + flex: 1;
  514 + padding: 12rpx 0 160rpx;
  515 +}
  516 +
  517 +.footer {
  518 + position: fixed;
  519 + left: 0;
  520 + right: 0;
  521 + bottom: 0;
  522 + padding: 32rpx;
  523 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  524 + background: #fff;
  525 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  526 + z-index: 10;
  527 +
  528 + .btn {
  529 + height: 80rpx;
  530 + line-height: 80rpx;
  531 + border-radius: 12rpx;
  532 + font-size: 32rpx;
  533 + }
  534 +
  535 + .submit {
  536 + background: $theme-primary;
  537 + color: #fff;
  538 + }
  539 +}
  540 +
  541 +.title-header {
  542 + display: flex;
  543 + align-items: center;
  544 + padding: 24rpx 32rpx 12rpx;
  545 + background-color: #ffffff;
  546 +
  547 + .title-header_icon {
  548 + width: 36rpx;
  549 + height: 36rpx;
  550 + margin-right: 12rpx;
  551 + }
  552 +
  553 + span {
  554 + font-size: 34rpx;
  555 + font-weight: 600;
  556 + color: rgba(0, 0, 0, 0.9);
  557 + }
  558 +}
  559 +
  560 +.mgb10 {
  561 + margin-bottom: 20rpx;
  562 +}
  563 +
  564 +::v-deep .uni-list {
  565 + .uni-easyinput {
  566 + display: flex;
  567 +
  568 + .uni-input-input {
  569 + color: rgba(0, 0, 0, 0.9);
  570 + }
  571 + }
  572 +
  573 + .uni-input-placeholder {
  574 + z-index: 1;
  575 + }
  576 +
  577 + .uni-input-input {
  578 + background-color: #ffffff;
  579 + }
  580 +
  581 + background: transparent;
  582 +
  583 + &-item {
  584 + &__extra-text {
  585 + font-size: 32rpx;
  586 + }
  587 +
  588 + &__content-title {
  589 + font-size: 32rpx;
  590 + color: rgba(0, 0, 0, 0.9);
  591 + }
  592 +
  593 + &__container {
  594 + padding: 32rpx;
  595 +
  596 + .uni-easyinput {
  597 + &__placeholder-class {
  598 + font-size: 32rpx;
  599 + color: rgba(0, 0, 0, 0.4);
  600 + }
  601 +
  602 + &__content {
  603 + border: none;
  604 + background-color: #ffffff !important;
  605 +
  606 + &-input {
  607 + padding-left: 0 !important;
  608 + height: 48rpx;
  609 + line-height: 48rpx;
  610 + font-size: 32rpx;
  611 + }
  612 +
  613 + .content-clear-icon {
  614 + font-size: 44rpx !important;
  615 + }
  616 + }
  617 + }
  618 +
  619 + .item-title,
  620 + .uni-list-item__content {
  621 + flex: none;
  622 + min-height: 48rpx;
  623 + line-height: 48rpx;
  624 + font-size: 32rpx;
  625 + position: relative;
  626 + width: 260rpx;
  627 + margin-right: 32rpx;
  628 + color: rgba(0, 0, 0, 0.9);
  629 + }
  630 + }
  631 +
  632 + &.select-item {
  633 + &.is-empty {
  634 + .uni-list-item__extra-text {
  635 + color: rgba(0, 0, 0, 0.4) !important;
  636 + }
  637 + }
  638 +
  639 + &.is-filled {
  640 + .uni-list-item__extra-text {
  641 + color: rgba(0, 0, 0, 0.9) !important;
  642 + }
  643 + }
  644 + }
  645 +
  646 + &.mgb10 {
  647 + margin-bottom: 20rpx;
  648 + }
  649 + }
  650 +}
  651 +</style>
  652 +
@@ -143,6 +143,23 @@ export default { @@ -143,6 +143,23 @@ 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 + text: '外客户资信',
  155 + icon: '/static/images/index/order_list.png',
  156 + link: '/pages/foreign_trade/index',
  157 + name: 'ForeignTrade'
  158 + }
  159 + ]
  160 +
  161 + },
  162 + {
146 title: '订货单管理', 163 title: '订货单管理',
147 items: [{ 164 items: [{
148 text: '订货单列表', 165 text: '订货单列表',
1 import CustomerDevelopViewer from '@/pages/dev_manage/viewer.vue' 1 import CustomerDevelopViewer from '@/pages/dev_manage/viewer.vue'
2 import CustomerCreditViewer from '@/pages/credit_manage/viewer.vue' 2 import CustomerCreditViewer from '@/pages/credit_manage/viewer.vue'
  3 +import DomesticCustomerCreditViewer from '@/pages/domestic_trade/domesticCreditViewer.vue'
  4 +import ForeignTradeCreditViewer from '@/pages/foreign_trade/foreignTradeCreditViewer.vue'
3 import RetailViewer from '@/pages/contract_retail/retailViewer.vue' 5 import RetailViewer from '@/pages/contract_retail/retailViewer.vue'
4 import ForeignStdViewer from '@/pages/contract_foreign_std/foreignStdViewer.vue' 6 import ForeignStdViewer from '@/pages/contract_foreign_std/foreignStdViewer.vue'
5 import StockViewer from '@/pages/contract_stock/stockViewer.vue' 7 import StockViewer from '@/pages/contract_stock/stockViewer.vue'
@@ -26,6 +28,8 @@ import FollowUpFormViewer from '@/pages/follow_up_form/viewer.vue' @@ -26,6 +28,8 @@ import FollowUpFormViewer from '@/pages/follow_up_form/viewer.vue'
26 export default function registerComponents(Vue) { 28 export default function registerComponents(Vue) {
27 Vue.component('CustomerDevelopViewer', CustomerDevelopViewer) 29 Vue.component('CustomerDevelopViewer', CustomerDevelopViewer)
28 Vue.component('CustomerCreditViewer', CustomerCreditViewer) 30 Vue.component('CustomerCreditViewer', CustomerCreditViewer)
  31 + Vue.component('DomesticCustomerCreditViewer', DomesticCustomerCreditViewer)
  32 + Vue.component('ForeignTradeCreditViewer', ForeignTradeCreditViewer)
29 Vue.component('RetailViewer', RetailViewer) 33 Vue.component('RetailViewer', RetailViewer)
30 Vue.component('StandardContractViewer', StandardContractViewer) 34 Vue.component('StandardContractViewer', StandardContractViewer)
31 Vue.component('FormalContractViewer', FormalContractViewer) 35 Vue.component('FormalContractViewer', FormalContractViewer)
@@ -48,4 +52,4 @@ export default function registerComponents(Vue) { @@ -48,4 +52,4 @@ export default function registerComponents(Vue) {
48 Vue.component('DraftDistAgmtViewer', DraftDistAgmtViewer) 52 Vue.component('DraftDistAgmtViewer', DraftDistAgmtViewer)
49 Vue.component('ForeignDraftDistAgmtViewer', ForeignDraftDistAgmtViewer) 53 Vue.component('ForeignDraftDistAgmtViewer', ForeignDraftDistAgmtViewer)
50 Vue.component('AgmtViewer', AgmtViewer) 54 Vue.component('AgmtViewer', AgmtViewer)
51 -}  
  55 +}
@@ -14,6 +14,18 @@ export const getSysFlowComponentPath = (bizFlag) => { @@ -14,6 +14,18 @@ export const getSysFlowComponentPath = (bizFlag) => {
14 case 'CUSTOMER_CREDIT_EDIT': // 客户资信 14 case 'CUSTOMER_CREDIT_EDIT': // 客户资信
15 componentPath = 'CustomerCreditViewer'; // 客户资信-审批 15 componentPath = 'CustomerCreditViewer'; // 客户资信-审批
16 break; 16 break;
  17 + case 'CUSTOMER_CREDIT_IN': // 客户资信(内贸)
  18 + componentPath = 'DomesticCustomerCreditViewer'; // 客户资信(内贸)-审批详情
  19 + break;
  20 + case 'CUSTOMER_CREDIT_IN_EDIT': // 客户资信(内贸)
  21 + componentPath = 'DomesticCustomerCreditViewer'; // 客户资信(内贸)-审批
  22 + break;
  23 + case 'CUSTOMER_CREDIT_OUT': // 客户资信(外贸)
  24 + componentPath = 'ForeignTradeCreditViewer'; // 客户资信(外贸)-审批详情
  25 + break;
  26 + case 'CUSTOMER_CREDIT_OUT_EDIT': // 客户资信(外贸)
  27 + componentPath = 'ForeignTradeCreditViewer'; // 客户资信(外贸)-审批
  28 + break;
17 case 'STANDARD_CONTRACT': // 标准合同 29 case 'STANDARD_CONTRACT': // 标准合同
18 componentPath = 'StandardContractViewer'; // 标准合同-审批详情 30 componentPath = 'StandardContractViewer'; // 标准合同-审批详情
19 break; 31 break;
@@ -114,4 +126,4 @@ export const getSysFlowComponentPath = (bizFlag) => { @@ -114,4 +126,4 @@ export const getSysFlowComponentPath = (bizFlag) => {
114 break; 126 break;
115 } 127 }
116 return componentPath; 128 return componentPath;
117 -};  
  129 +};