Commit 9da75ad2771109bb5232343e7fcf9751e27e0263

Authored by gesilong
2 parents b2297332 a9831143

Merge branch 'cjerp-2.0' into publish_cjerp

Too many changes to show.

To preserve performance only 13 of 18 files are displayed.

  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 +}
  51 +export function getRegionApi() {
  52 + return request({
  53 + url: '/system/dept/getRegion',
  54 + method: 'get'
  55 + })
  56 +}
  57 +export function getAllRegionApi(purchaseDepartment) {
  58 + return request({
  59 + url: '/system/dept/getAllRegion',
  60 + method: 'get',
  61 + params: { purchaseDepartment }
  62 + })
  63 +}
\ No newline at end of file
... ...
  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 +}
... ...
... ... @@ -4,8 +4,8 @@ module.exports = {
4 4 themeColor: '#3d48a3',
5 5
6 6 // baseUrl: 'http://ft.wecando21cn.com/api',
7   - baseUrl: 'http://gjtd.ahcjxc.com:81/api',
8   - // baseUrl: 'http://erp.qgutech.com/api',
  7 + // baseUrl: 'http://gjtd.ahcjxc.com:81/api',
  8 + baseUrl: 'http://erp.qgutech.com/api',
9 9 // baseUrl: 'http://10.9.5.246:8081',
10 10 // 应用信息
11 11 appInfo: {
... ...
... ... @@ -212,6 +212,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 279 "path": "pages/order_list/index",
216 280 "style": {
217 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 class="select-item" :class="form.purchaseDepartment ? 'is-filled' : 'is-empty'" clickable
  303 + @click="openSheet('purchaseDepartment')" :rightText="displayLabel('purchaseDepartmentName')" showArrow>
  304 + <template v-slot:body>
  305 + <view class="item-title"><text>采购处</text></view>
  306 + </template>
  307 + </uni-list-item>
  308 +
  309 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  310 + @click="openSheet('region')" :rightText="displayLabel('region')" showArrow>
  311 + <template v-slot:body>
  312 + <view class="item-title"><text>区域</text></view>
  313 + </template>
  314 + </uni-list-item>
  315 +
  316 + <uni-list-item title="评审有效期">
  317 + <template v-slot:footer>
  318 + <uni-datetime-picker type="date" v-model="form.reviewValidUntil" />
  319 + </template>
  320 + </uni-list-item>
  321 +
  322 + <uni-list-item class="mgb10" title="附件">
  323 + <template v-slot:footer>
  324 + <view class="attach-box">
  325 + <view v-for="(f, idx) in attachmentFiles" :key="idx" class="attach-row">
  326 + <FileUpload :value="f" @input="onAttachmentInput(idx, $event)" />
  327 + <text class="attach-del" @click.stop="removeAttachment(idx)">删除</text>
  328 + </view>
  329 + <view class="attach-row">
  330 + <FileUpload :value="newAttachment" @input="onAddAttachment" />
  331 + </view>
  332 + </view>
  333 + </template>
  334 + </uni-list-item>
  335 + </uni-list>
  336 + </scroll-view>
  337 +
  338 + <view class="footer">
  339 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '提交中...' : '提交' }}</button>
  340 + </view>
  341 +
  342 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  343 + @confirm="onSheetConfirm" />
  344 + <MultiSelectSheet :visible.sync="multiSheet.visible" :title="multiSheet.title" :options="multiSheet.options"
  345 + v-model="multiSheet.value" @confirm="onMultiSheetConfirm" />
  346 + </view>
  347 +</template>
  348 +
  349 +<script>
  350 +import FileUpload from '@/components/file-upload/index.vue'
  351 +import SingleSelectSheet from '@/components/single-select/index.vue'
  352 +import MultiSelectSheet from '@/components/multi-select/index.vue'
  353 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  354 +import { domesticCustomerCreditSaveApi, getPurchaseDeptApi, getAllRegionApi, getRegionApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  355 +
  356 +export default {
  357 + name: 'DomesticTradeAdd',
  358 + components: { FileUpload, SingleSelectSheet, MultiSelectSheet },
  359 + data() {
  360 + return {
  361 + submitting: false,
  362 + newAttachment: { id: '', name: '' },
  363 + attachmentFiles: [],
  364 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  365 + multiSheet: { visible: false, title: '', options: [], field: '', value: '' },
  366 + dicOptions: {
  367 + COMPANY_NATURE: [],
  368 + DEVELOP_NEW: [],
  369 + OPERATION_METHOD: [],
  370 + PURCHASE_SOURCE: []
  371 + },
  372 + yesNoOptions: [
  373 + { label: '是', value: true },
  374 + { label: '否', value: false }
  375 + ],
  376 + companyNatureOptions: [],
  377 + operationMethodOptions: [],
  378 + developNewOptions: [],
  379 + purchaseSourceOptions: [],
  380 + regionOptions: [],
  381 + purchaseDeptOptions: [],
  382 + form: {
  383 + unitName: '',
  384 + customerShortName: '',
  385 + companyNature: '',
  386 + companyNatureName: '',
  387 + companyNatureOther: '',
  388 + bankName: '',
  389 + bankAccount: '',
  390 + registeredCapital: '',
  391 + legalRepresentative: '',
  392 + companyEstablishedTime: '',
  393 + address: '',
  394 + businessPrincipal: '',
  395 + businessPrincipalPosition: '',
  396 + businessPrincipalPhone: '',
  397 + legalBusinessRelation: '',
  398 + factoryOfficeProperty: '',
  399 + factoryOfficeArea: '',
  400 + warehouseYardProperty: '',
  401 + warehouseYardArea: '',
  402 + mainEquipment: '',
  403 + normalInventory: '',
  404 + mainVarieties: '',
  405 + monthlyPurchaseVolume: '',
  406 + purchaseSource: '',
  407 + stockInProductName: '',
  408 + productName: '',
  409 + capacity: '',
  410 + salesChannel: '',
  411 + hasPreferentialPolicy: null,
  412 + investInFutures: null,
  413 + hasPenaltyRecord: null,
  414 + businessScopeMatch: null,
  415 + commonMaterialIssue: '',
  416 + otherIssue: '',
  417 + firstCooperationYear: '',
  418 + isNewDevelopment: '',
  419 + operationMode: '',
  420 + hasFailedPlanRecord: null,
  421 + hasPlanPerformanceIssue: null,
  422 + accountingProcess: '',
  423 + invoiceNameMatch: null,
  424 + outboundProcessStandard: null,
  425 + transportMode: '',
  426 + attachmentFileIds: '',
  427 + attachmentFileNames: '',
  428 + investigatorId: '',
  429 + investigatorName: '',
  430 + purchaseDepartment: '',
  431 + purchaseDepartmentName: '',
  432 + region: '',
  433 + regionName: '',
  434 + reviewValidUntil: ''
  435 + }
  436 + }
  437 + },
  438 + created() {
  439 + this.initPage()
  440 + },
  441 + computed: {
  442 + showCompanyNatureOther() {
  443 + const v = String(this.form.companyNature || '')
  444 + return v.split(',').includes('OTHER')
  445 + }
  446 + },
  447 + methods: {
  448 + async initPage() {
  449 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  450 + this.form.investigatorId = u && u.id ? String(u.id) : ''
  451 + this.form.investigatorName = u && u.name ? String(u.name) : ''
  452 + await this.loadDicData()
  453 + await this.loadPurchaseDeptList()
  454 + await this.loadRegionOptions()
  455 + },
  456 + async loadDicData() {
  457 + try {
  458 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  459 + const next = {
  460 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  461 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  462 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  463 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  464 + }
  465 + this.dicOptions = next
  466 + console.log(next,'next')
  467 + this.companyNatureOptions = this.dicToSheetOptions(next.COMPANY_NATURE)
  468 + this.developNewOptions = this.dicToSheetOptions(next.DEVELOP_NEW)
  469 + this.operationMethodOptions = this.dicToSheetOptions(next.OPERATION_METHOD)
  470 + this.purchaseSourceOptions = this.dicToSheetOptions(next.PURCHASE_SOURCE)
  471 + this.form.companyNatureName = this.labelsOfOptions(this.companyNatureOptions, this.form.companyNature)
  472 + } catch (e) {
  473 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  474 + this.companyNatureOptions = []
  475 + this.developNewOptions = []
  476 + this.operationMethodOptions = []
  477 + this.purchaseSourceOptions = []
  478 + uni.showToast({ title: '字典加载失败', icon: 'none' })
  479 + }
  480 + },
  481 + dicToSheetOptions(items) {
  482 + const list = Array.isArray(items) ? items : []
  483 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  484 + },
  485 + async loadPurchaseDeptList() {
  486 + try {
  487 + const res = await getPurchaseDeptApi()
  488 + const raw = res && res.data != null ? res.data : []
  489 + this.purchaseDeptOptions = this.normalizeRegionOptions(raw)
  490 + } catch (e) {
  491 + this.purchaseDeptOptions = []
  492 + }
  493 + },
  494 + normalizeRegionOptions(raw) {
  495 + const list = Array.isArray(raw)
  496 + ? raw
  497 + : (Array.isArray(raw && raw.data) ? raw.data : (Array.isArray(raw && raw.rows) ? raw.rows : []))
  498 + return list.map(it => {
  499 + const id = it && (it.id != null ? it.id : (it.value != null ? it.value : (it.regionId != null ? it.regionId : '')))
  500 + const name = it && (it.name != null ? it.name : (it.label != null ? it.label : (it.regionName != null ? it.regionName : '')))
  501 + return { label: name != null ? String(name) : '', value: id != null ? String(id) : '' }
  502 + }).filter(it => it.value)
  503 + },
  504 + getOptionLabel(options, value) {
  505 + const v = value != null ? String(value) : ''
  506 + if (!v) return ''
  507 + const match = (options || []).find(o => String(o.value) === v)
  508 + return match ? String(match.label || '') : ''
  509 + },
  510 + syncRegionWithOptions() {
  511 + const label = this.getOptionLabel(this.regionOptions, this.form.region)
  512 + if (!label) {
  513 + this.form.region = ''
  514 + this.form.regionName = ''
  515 + return
  516 + }
  517 + this.form.regionName = label
  518 + },
  519 + async loadRegionOptions() {
  520 + let defaultRegionId = ''
  521 + let defaultRegionName = ''
  522 + try {
  523 + const regionRes = await getRegionApi()
  524 + const regionData = (regionRes && regionRes.data != null) ? regionRes.data : null
  525 + const parsed = regionData ? this.parseRegionIdAndName(regionData) : { id: '', name: '' }
  526 + if (parsed.id) {
  527 + defaultRegionId = parsed.id
  528 + defaultRegionName = parsed.name
  529 + }
  530 + } catch (e) {
  531 + // fall through to getAllRegionApi
  532 + }
  533 + const purchaseDepartment = this.form.purchaseDepartment ? String(this.form.purchaseDepartment) : ''
  534 + if (!purchaseDepartment) {
  535 + if (defaultRegionId) {
  536 + this.regionOptions = [{ label: defaultRegionName || String(defaultRegionId), value: defaultRegionId }]
  537 + this.form.region = defaultRegionId
  538 + this.form.regionName = defaultRegionName || String(defaultRegionId)
  539 + } else {
  540 + this.regionOptions = []
  541 + this.form.region = ''
  542 + this.form.regionName = ''
  543 + }
  544 + return
  545 + }
  546 + try {
  547 + const res = await getAllRegionApi(purchaseDepartment)
  548 + const raw = res && res.data != null ? res.data : []
  549 + this.regionOptions = this.normalizeRegionOptions(raw)
  550 + if (defaultRegionId) {
  551 + const label = this.getOptionLabel(this.regionOptions, defaultRegionId)
  552 + if (label) {
  553 + this.form.region = defaultRegionId
  554 + this.form.regionName = label
  555 + } else {
  556 + // 默认区域不在完整列表中,仍保留为选中项
  557 + this.regionOptions.push({ label: defaultRegionName || String(defaultRegionId), value: defaultRegionId })
  558 + this.form.region = defaultRegionId
  559 + this.form.regionName = defaultRegionName || String(defaultRegionId)
  560 + }
  561 + } else {
  562 + this.syncRegionWithOptions()
  563 + }
  564 + } catch (e) {
  565 + this.regionOptions = []
  566 + this.form.region = ''
  567 + this.form.regionName = ''
  568 + }
  569 + },
  570 + parseRegionIdAndName(raw) {
  571 + if (!raw) return { id: '', name: '' }
  572 + if (Array.isArray(raw)) return this.parseRegionIdAndName(raw[0])
  573 + if (typeof raw === 'string' || typeof raw === 'number') return { id: String(raw), name: '' }
  574 + const id = raw.id != null ? raw.id : (raw.value != null ? raw.value : (raw.regionId != null ? raw.regionId : ''))
  575 + const name = raw.name != null ? raw.name : (raw.label != null ? raw.label : (raw.regionName != null ? raw.regionName : ''))
  576 + return { id: id != null ? String(id) : '', name: name != null ? String(name) : '' }
  577 + },
  578 + labelsOfOptions(options, csv) {
  579 + const v = csv == null ? '' : String(csv)
  580 + if (!v) return ''
  581 + const parts = v.split(',').filter(Boolean)
  582 + if (!parts.length) return ''
  583 + const labels = []
  584 + ;(options || []).forEach(opt => {
  585 + const ov = opt && opt.value != null ? String(opt.value) : ''
  586 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  587 + })
  588 + return labels.filter(Boolean).join(',') || ''
  589 + },
  590 + displayLabel(field) {
  591 + const m = this.form || {}
  592 + const map = {
  593 + purchaseDepartmentName: '请选择采购处',
  594 + companyNatureName: '请选择公司性质',
  595 + region: '请选择区域',
  596 + purchaseSource: '请选择',
  597 + operationMode: '请选择',
  598 + isNewDevelopment: '请选择',
  599 + hasPreferentialPolicy: '请选择',
  600 + investInFutures: '请选择',
  601 + hasPenaltyRecord: '请选择',
  602 + businessScopeMatch: '请选择',
  603 + hasFailedPlanRecord: '请选择',
  604 + hasPlanPerformanceIssue: '请选择',
  605 + invoiceNameMatch: '请选择',
  606 + outboundProcessStandard: '请选择'
  607 + }
  608 + if (field === 'companyNatureName') {
  609 + const val = m[field]
  610 + return val ? String(val) : map[field]
  611 + }
  612 + if (field === 'purchaseSource') {
  613 + const v = m.purchaseSource
  614 + return v ? getDicName('PURCHASE_SOURCE', String(v), this.dicOptions.PURCHASE_SOURCE) : map[field]
  615 + }
  616 + if (field === 'operationMode') {
  617 + const v = m.operationMode
  618 + return v ? getDicName('OPERATION_METHOD', String(v), this.dicOptions.OPERATION_METHOD) : map[field]
  619 + }
  620 + if (field === 'isNewDevelopment') {
  621 + const v = m.isNewDevelopment
  622 + return v ? getDicName('DEVELOP_NEW', String(v), this.dicOptions.DEVELOP_NEW) : map[field]
  623 + }
  624 + if (field === 'region') {
  625 + const v = m.region
  626 + if (!v) return map[field]
  627 + return this.getOptionLabel(this.regionOptions, v) || map[field]
  628 + }
  629 + if (field === 'purchaseDepartmentName') {
  630 + return this.getOptionLabel(this.purchaseDeptOptions, m.purchaseDepartment) || map[field]
  631 + }
  632 + const v = m[field]
  633 + if (v === true) return '是'
  634 + if (v === false) return '否'
  635 + return map[field] || '请选择'
  636 + },
  637 + openSheet(field) {
  638 + const map = {
  639 + region: { title: '区域', options: this.regionOptions },
  640 + purchaseDepartment: { title: '采购处', options: this.purchaseDeptOptions },
  641 + purchaseSource: { title: '收购来源', options: this.purchaseSourceOptions },
  642 + operationMode: { title: '操作方式', options: this.operationMethodOptions },
  643 + isNewDevelopment: { title: '是否新开发', options: this.developNewOptions },
  644 + hasPreferentialPolicy: { title: '是否享有优惠政策', options: this.yesNoOptions },
  645 + investInFutures: { title: '是否投资期货', options: this.yesNoOptions },
  646 + hasPenaltyRecord: { title: '是否有被处罚记录', options: this.yesNoOptions },
  647 + businessScopeMatch: { title: '实际经营范围与法定经营范围是否相符', options: this.yesNoOptions },
  648 + hasFailedPlanRecord: { title: '是否有计划落空的不良记录', options: this.yesNoOptions },
  649 + hasPlanPerformanceIssue: { title: '是否有计划履行不到位现象', options: this.yesNoOptions },
  650 + invoiceNameMatch: { title: '开票品名与出库单品名是否一致', options: this.yesNoOptions },
  651 + outboundProcessStandard: { title: '出库流程是否规范', options: this.yesNoOptions }
  652 + }
  653 + const cfg = map[field]
  654 + if (!cfg) return
  655 + const current = this.form[field]
  656 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  657 + this.sheet = {
  658 + ...this.sheet,
  659 + visible: true,
  660 + title: cfg.title,
  661 + options: cfg.options || [],
  662 + field,
  663 + value: match ? match.value : current
  664 + }
  665 + },
  666 + openMultiSheet(field) {
  667 + if (field !== 'companyNature') return
  668 + this.multiSheet = {
  669 + ...this.multiSheet,
  670 + visible: true,
  671 + title: '公司性质',
  672 + options: this.companyNatureOptions || [],
  673 + field,
  674 + value: this.form.companyNature || ''
  675 + }
  676 + },
  677 + onSheetConfirm({ value, label }) {
  678 + const field = this.sheet.field
  679 + if (!field) return
  680 + this.form[field] = value
  681 + if (field === 'region') this.form.regionName = label != null ? String(label) : this.getOptionLabel(this.regionOptions, value)
  682 + if (field === 'purchaseDepartment') {
  683 + this.form.purchaseDepartmentName = label != null ? String(label) : this.getOptionLabel(this.purchaseDeptOptions, value)
  684 + console.log(value,'value')
  685 + console.log(this.purchaseDeptOptions,'purchaseDeptOptions')
  686 + console.log(this.form.purchaseDepartmentName ,'purchasthis.form.purchaseDepartmentName eDeptOptions')
  687 + this.loadRegionOptions()
  688 + }
  689 + this.sheet.visible = false
  690 + },
  691 + onMultiSheetConfirm({ value, label }) {
  692 + const field = this.multiSheet.field
  693 + if (field === 'companyNature') {
  694 + const normalized = this.normalizeCompanyNature(value)
  695 + this.form.companyNature = normalized.value
  696 + this.form.companyNatureName = normalized.label
  697 + if (!this.showCompanyNatureOther) this.form.companyNatureOther = ''
  698 + }
  699 + this.multiSheet.visible = false
  700 + },
  701 + normalizeCompanyNature(valueStr) {
  702 + const selected = (valueStr ? String(valueStr).split(',').filter(Boolean) : [])
  703 + const finalSelected = selected.slice(0)
  704 + const orderedValues = []
  705 + const orderedLabels = []
  706 + ;(this.companyNatureOptions || []).forEach(opt => {
  707 + const v = opt && opt.value != null ? String(opt.value) : ''
  708 + if (v && finalSelected.includes(v)) {
  709 + orderedValues.push(v)
  710 + orderedLabels.push(opt.label != null ? String(opt.label) : '')
  711 + }
  712 + })
  713 + return { value: orderedValues.join(','), label: orderedLabels.join(',') }
  714 + },
  715 + removeAttachment(idx) {
  716 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  717 + list.splice(idx, 1)
  718 + this.attachmentFiles = list
  719 + },
  720 + onAddAttachment(val) {
  721 + const payload = val || { id: '', name: '' }
  722 + if (!payload.id) return
  723 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  724 + list.push(payload)
  725 + this.attachmentFiles = list
  726 + this.newAttachment = { id: '', name: '' }
  727 + },
  728 + onAttachmentInput(idx, val) {
  729 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  730 + list[idx] = val || { id: '', name: '' }
  731 + this.attachmentFiles = list
  732 + },
  733 + validate() {
  734 + const requiredTextFields = [
  735 + { key: 'unitName', label: '单位名称' },
  736 + { key: 'customerShortName', label: '客户简称' },
  737 + { key: 'companyNature', label: '公司性质' },
  738 + { key: 'bankName', label: '开户行' },
  739 + { key: 'bankAccount', label: '账号' },
  740 + { key: 'legalRepresentative', label: '法人代表' },
  741 + { key: 'companyEstablishedTime', label: '公司成立时间' },
  742 + { key: 'address', label: '地址' },
  743 + { key: 'businessPrincipal', label: '业务负责人' },
  744 + { key: 'businessPrincipalPosition', label: '职务' },
  745 + { key: 'businessPrincipalPhone', label: '电话' },
  746 + { key: 'legalBusinessRelation', label: '法人与业务负责人关系' },
  747 + { key: 'factoryOfficeProperty', label: '生产厂房及办公楼产权' },
  748 + { key: 'factoryOfficeArea', label: '生产厂房及办公楼面积' },
  749 + { key: 'warehouseYardProperty', label: '仓库或货场产权' },
  750 + { key: 'warehouseYardArea', label: '仓库或货场产权面积' },
  751 + { key: 'mainEquipment', label: '主要生产设备' },
  752 + { key: 'normalInventory', label: '正常库存量' },
  753 + { key: 'mainVarieties', label: '主要品种' },
  754 + { key: 'monthlyPurchaseVolume', label: '月度收购量' },
  755 + { key: 'purchaseSource', label: '收购来源' },
  756 + { key: 'stockInProductName', label: '入库品名' },
  757 + { key: 'productName', label: '产品名称' },
  758 + { key: 'capacity', label: '产能' },
  759 + { key: 'salesChannel', label: '销售渠道' },
  760 + { key: 'firstCooperationYear', label: '首次合作年份' },
  761 + { key: 'isNewDevelopment', label: '是否新开发' },
  762 + { key: 'operationMode', label: '操作方式' },
  763 + { key: 'accountingProcess', label: '进销账务如何处理' },
  764 + { key: 'transportMode', label: '运输方式' },
  765 + { key: 'commonMaterialIssue', label: '常见料质问题' },
  766 + { key: 'otherIssue', label: '合作中的其它问题' },
  767 + { key: 'purchaseDepartment', label: '采购处' },
  768 + { key: 'reviewValidUntil', label: '评审有效期' },
  769 + { key: 'investigatorId', label: '资信调查人ID' }
  770 + ]
  771 + if (Array.isArray(this.regionOptions) && this.regionOptions.length) {
  772 + requiredTextFields.push({ key: 'region', label: '区域' })
  773 + }
  774 + for (let i = 0; i < requiredTextFields.length; i++) {
  775 + const f = requiredTextFields[i]
  776 + const v = this.form && this.form[f.key]
  777 + if (v == null || String(v).trim() === '') {
  778 + uni.showToast({ title: `${f.label}必填`, icon: 'none' })
  779 + return false
  780 + }
  781 + }
  782 +
  783 + const registeredCapital = Number(this.form.registeredCapital)
  784 + if (!Number.isFinite(registeredCapital) || registeredCapital < 0) {
  785 + uni.showToast({ title: '注册资金请填写数字', icon: 'none' })
  786 + return false
  787 + }
  788 +
  789 + const requiredBoolFields = [
  790 + { key: 'hasPreferentialPolicy', label: '是否享有优惠政策' },
  791 + { key: 'investInFutures', label: '是否投资期货' },
  792 + { key: 'hasPenaltyRecord', label: '是否有被处罚记录' },
  793 + { key: 'businessScopeMatch', label: '经营范围是否相符' },
  794 + { key: 'hasFailedPlanRecord', label: '计划落空不良记录' },
  795 + { key: 'hasPlanPerformanceIssue', label: '计划履行不到位现象' },
  796 + { key: 'invoiceNameMatch', label: '开票品名是否一致' },
  797 + { key: 'outboundProcessStandard', label: '出库流程是否规范' }
  798 + ]
  799 + for (let i = 0; i < requiredBoolFields.length; i++) {
  800 + const f = requiredBoolFields[i]
  801 + const v = this.form && this.form[f.key]
  802 + if (!(v === true || v === false)) {
  803 + uni.showToast({ title: `请选择${f.label}`, icon: 'none' })
  804 + return false
  805 + }
  806 + }
  807 +
  808 + const files = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.filter(it => it && it.id) : []
  809 + if (!files.length) {
  810 + uni.showToast({ title: '请上传附件', icon: 'none' })
  811 + return false
  812 + }
  813 +
  814 + const phone = String(this.form.businessPrincipalPhone || '').trim()
  815 + if (phone && !/^1\d{10}$/.test(phone)) {
  816 + uni.showToast({ title: '电话请输入11位手机号', icon: 'none' })
  817 + return false
  818 + }
  819 + const year = String(this.form.firstCooperationYear || '').trim()
  820 + if (year && !/^\d{4}$/.test(year)) {
  821 + uni.showToast({ title: '首次合作年份请填写4位年份', icon: 'none' })
  822 + return false
  823 + }
  824 + return true
  825 + },
  826 + buildPayload() {
  827 + const payload = { ...this.form }
  828 + if (!this.showCompanyNatureOther) payload.companyNatureOther = ''
  829 + delete payload.companyNatureName
  830 + delete payload.investigatorName
  831 + delete payload.purchaseDepartmentName
  832 + delete payload.regionName
  833 + payload.registeredCapital = Number(payload.registeredCapital)
  834 + const files = (Array.isArray(this.attachmentFiles) ? this.attachmentFiles : []).filter(it => it && it.id)
  835 + payload.attachmentFileIds = files.map(it => String(it.id || '')).filter(Boolean).join(',')
  836 + payload.attachmentFileNames = files.map(it => String(it.name || '')).filter(Boolean).join(',')
  837 + return payload
  838 + },
  839 + async onSubmit() {
  840 + if (this.submitting) return
  841 + if (!this.validate()) return
  842 + this.submitting = true
  843 + const payload = this.buildPayload()
  844 + try {
  845 + await domesticCustomerCreditSaveApi(payload)
  846 + uni.showToast({ title: '提交成功', icon: 'success' })
  847 + try { uni.setStorageSync('DOMESTIC_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  848 + setTimeout(() => { uni.redirectTo({ url: '/pages/domestic_trade/index' }) }, 300)
  849 + } catch (e) {
  850 + uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
  851 + } finally {
  852 + this.submitting = false
  853 + }
  854 + },
  855 + }
  856 +}
  857 +</script>
  858 +
  859 +<style lang="scss" scoped>
  860 +.page {
  861 + display: flex;
  862 + flex-direction: column;
  863 + height: 100%;
  864 +}
  865 +
  866 +.scroll {
  867 + flex: 1;
  868 + padding: 12rpx 0 160rpx;
  869 +}
  870 +
  871 +.footer {
  872 + position: fixed;
  873 + left: 0;
  874 + right: 0;
  875 + bottom: 0;
  876 + padding: 32rpx;
  877 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  878 + background: #fff;
  879 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  880 + z-index: 10;
  881 +
  882 + .btn {
  883 + height: 80rpx;
  884 + line-height: 80rpx;
  885 + border-radius: 12rpx;
  886 + font-size: 32rpx;
  887 + }
  888 +
  889 + .submit {
  890 + background: $theme-primary;
  891 + color: #fff;
  892 + }
  893 +}
  894 +
  895 +.title-header {
  896 + display: flex;
  897 + align-items: center;
  898 + padding: 24rpx 32rpx 12rpx;
  899 + background-color: #ffffff;
  900 + .title-header_icon {
  901 + width: 36rpx;
  902 + height: 36rpx;
  903 + margin-right: 12rpx;
  904 + }
  905 +
  906 + span {
  907 + font-size: 34rpx;
  908 + font-weight: 600;
  909 + color: rgba(0, 0, 0, 0.9);
  910 + }
  911 +}
  912 +
  913 +.mgb10 {
  914 + margin-bottom: 20rpx;
  915 +}
  916 +
  917 +.amount-row {
  918 + display: flex;
  919 + align-items: center;
  920 + gap: 12rpx;
  921 +
  922 + .unit, .prefix, .suffix {
  923 + font-size: 28rpx;
  924 + color: rgba(0, 0, 0, 0.6);
  925 + white-space: nowrap;
  926 + }
  927 +}
  928 +
  929 +.attach-box {
  930 + display: flex;
  931 + flex-direction: column;
  932 + align-items: flex-end;
  933 + gap: 16rpx;
  934 + width: 100%;
  935 +}
  936 +
  937 +.attach-row {
  938 + width: 100%;
  939 + display: flex;
  940 + justify-content: flex-end;
  941 + align-items: center;
  942 + gap: 20rpx;
  943 +}
  944 +
  945 +.attach-del {
  946 + font-size: 28rpx;
  947 + color: #D54941;
  948 +}
  949 +
  950 +::v-deep .uni-list {
  951 + .uni-easyinput {
  952 + display: flex;
  953 +
  954 + .uni-input-input {
  955 + color: rgba(0, 0, 0, 0.9);
  956 + }
  957 + }
  958 +
  959 + .uni-input-placeholder {
  960 + z-index: 1;
  961 + }
  962 +
  963 + .uni-input-input {
  964 + background-color: #ffffff;
  965 + }
  966 +
  967 + background: transparent;
  968 +
  969 + &-item {
  970 + &__extra-text {
  971 + font-size: 32rpx;
  972 + }
  973 +
  974 + &__content-title {
  975 + font-size: 32rpx;
  976 + color: rgba(0, 0, 0, 0.9);
  977 + }
  978 +
  979 + &__container {
  980 + padding: 32rpx;
  981 +
  982 + .uni-easyinput {
  983 + &__placeholder-class {
  984 + font-size: 32rpx;
  985 + color: rgba(0, 0, 0, 0.4);
  986 + }
  987 +
  988 + &__content {
  989 + border: none;
  990 + background-color: #ffffff !important;
  991 +
  992 + &-input {
  993 + padding-left: 0 !important;
  994 + height: 48rpx;
  995 + line-height: 48rpx;
  996 + font-size: 32rpx;
  997 + }
  998 +
  999 + .content-clear-icon {
  1000 + font-size: 44rpx !important;
  1001 + }
  1002 + }
  1003 + }
  1004 +
  1005 + .item-title,
  1006 + .uni-list-item__content {
  1007 + flex: none;
  1008 + min-height: 48rpx;
  1009 + line-height: 48rpx;
  1010 + font-size: 32rpx;
  1011 + position: relative;
  1012 + width: 210rpx;
  1013 + margin-right: 32rpx;
  1014 + color: rgba(0, 0, 0, 0.9);
  1015 +
  1016 + .required {
  1017 + color: red;
  1018 + position: absolute;
  1019 + top: 50%;
  1020 + transform: translateY(-50%);
  1021 + left: -16rpx;
  1022 + }
  1023 + }
  1024 + }
  1025 +
  1026 + &.select-item {
  1027 + &.is-empty {
  1028 + .uni-list-item__extra-text {
  1029 + color: rgba(0, 0, 0, 0.4) !important;
  1030 + }
  1031 + }
  1032 +
  1033 + &.is-filled {
  1034 + .uni-list-item__extra-text {
  1035 + color: rgba(0, 0, 0, 0.9) !important;
  1036 + }
  1037 + }
  1038 + }
  1039 +
  1040 + &.mgb10 {
  1041 + margin-bottom: 20rpx;
  1042 + }
  1043 + }
  1044 +}
  1045 +</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(regionName) }}</text></view>
  79 + <view class="row"><text class="label">评审有效期</text><text class="value">{{ safeText(form.reviewValidUntil) }}</text></view>
  80 + <view class="row">
  81 + <text class="label">附件</text>
  82 + <view class="value">
  83 + <view v-if="!attachments.length" class="value">-</view>
  84 + <view v-for="item in attachments" :key="item.id || item.name" class="file-item" @click="onDownload(item)">
  85 + <text class="value act">{{ item.name }}</text>
  86 + </view>
  87 + </view>
  88 + </view>
  89 + </view>
  90 + </view>
  91 + </scroll-view>
  92 + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" />
  93 + </view>
  94 +</template>
  95 +
  96 +<script>
  97 +import { downloadFile } from '@/utils/downloadFile.js'
  98 +import DetailButtons from '@/components/detail-buttons/index.vue'
  99 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  100 +import { domesticCustomerCreditCancelApi, domesticCustomerCreditGetApi, getPurchaseDeptApi, getAllRegionApi } 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 + regionOptions: [],
  120 + buttons: [{
  121 + text: '审核详情',
  122 + visible: true,
  123 + variant: 'outline',
  124 + event: 'auditDetail',
  125 + },{
  126 + text: '审核',
  127 + visible: true,
  128 + variant: 'primary',
  129 + event: 'audit',
  130 + },{
  131 + text: '编辑',
  132 + visible: true,
  133 + variant: 'outline',
  134 + event: 'edit',
  135 + },
  136 + // {
  137 + // text: '申请变更',
  138 + // visible: true,
  139 + // variant: 'outline',
  140 + // event: 'changeApply',
  141 + // },
  142 + {
  143 + text: '取消',
  144 + visible: true,
  145 + variant: 'outline',
  146 + event: 'cancel',
  147 + }]
  148 + }
  149 + },
  150 + computed: {
  151 + displayButtons() {
  152 + const s = this.form && this.form.status || false
  153 + const d = this.form && this.form.showExamineDetail || false
  154 + const e = this.form && this.form.showExamine || false
  155 + return [
  156 + { ...this.buttons[0], visible: d && this.$auth.hasPermi('procure-manage:domestic-trade:review') },
  157 + { ...this.buttons[1], visible: s === 'AUDIT' && e && this.$auth.hasPermi('procure-manage:domestic-trade:approve') },
  158 + { ...this.buttons[2], visible: s === 'REFUSE' && this.$auth.hasPermi('procure-manage:domestic-trade:modify') },
  159 + // { ...this.buttons[3], visible: s === 'PASS' && this.$auth.hasPermi('procure-manage:domestic-trade:change') },
  160 + { ...this.buttons[3], visible: s === 'REFUSE' && this.$auth.hasPermi('procure-manage:domestic-trade:cancel') },
  161 + ]
  162 + },
  163 + companyNatureOptions() {
  164 + return this.dicToSheetOptions(this.dicOptions.COMPANY_NATURE)
  165 + },
  166 + attachments() {
  167 + const f = this.form || {}
  168 + const ids = f.attachmentFileIds != null ? String(f.attachmentFileIds) : ''
  169 + const names = f.attachmentFileNames != null ? String(f.attachmentFileNames) : ''
  170 + const idArr = ids ? ids.split(',').map(s => s.trim()).filter(Boolean) : []
  171 + const nameArr = names ? names.split(',') : []
  172 + if (idArr.length) {
  173 + return idArr.map((id, i) => ({ id, name: (nameArr[i] != null ? String(nameArr[i]) : '') }))
  174 + }
  175 + const legacy = Array.isArray(f.attachments) ? f.attachments : []
  176 + return legacy.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  177 + },
  178 + showCompanyNatureOther() {
  179 + const v = String((this.form && this.form.companyNature) || '')
  180 + return v.split(',').includes('OTHER')
  181 + },
  182 + companyNatureName() {
  183 + return this.safeText(this.form.companyNatureName) || this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  184 + },
  185 + purchaseSourceName() {
  186 + const v = this.form && this.form.purchaseSource != null ? String(this.form.purchaseSource) : ''
  187 + return v ? getDicName('PURCHASE_SOURCE', v, this.dicOptions.PURCHASE_SOURCE) : '-'
  188 + },
  189 + operationModeName() {
  190 + const v = this.form && this.form.operationMode != null ? String(this.form.operationMode) : ''
  191 + return v ? getDicName('OPERATION_METHOD', v, this.dicOptions.OPERATION_METHOD) : '-'
  192 + },
  193 + isNewDevelopmentName() {
  194 + const v = this.form && this.form.isNewDevelopment != null ? String(this.form.isNewDevelopment) : ''
  195 + return v ? getDicName('DEVELOP_NEW', v, this.dicOptions.DEVELOP_NEW) : '-'
  196 + },
  197 + purchaseDepartmentName() {
  198 + if (this.purchaseDept && this.purchaseDept.name != null) return String(this.purchaseDept.name)
  199 + const v = this.form && this.form.purchaseDepartmentName != null ? String(this.form.purchaseDepartmentName) : ''
  200 + return v || '-'
  201 + },
  202 + regionName() {
  203 + const name = this.safeText(this.form && this.form.regionName)
  204 + if (name) return name
  205 + const id = this.form && this.form.region != null ? String(this.form.region) : ''
  206 + const labelFromOptions = this.getOptionLabel(this.regionOptions, id)
  207 + if (labelFromOptions) return labelFromOptions
  208 + return id || '-'
  209 + }
  210 + },
  211 + created() {
  212 + this.loadDicData()
  213 + this.loadPurchaseDeptOptions()
  214 + },
  215 + onShow() {
  216 + const options = (this.$route && this.$route.query) ? this.$route.query : {}
  217 + const id = options && options.id ? String(options.id) : ''
  218 + this.id = id
  219 + this.loadDetail()
  220 + },
  221 + methods: {
  222 + async loadDicData() {
  223 + try {
  224 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  225 + this.dicOptions = {
  226 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  227 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  228 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  229 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  230 + }
  231 + } catch (e) {
  232 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  233 + }
  234 + },
  235 + async loadPurchaseDeptOptions() {
  236 + try {
  237 + const res = await getPurchaseDeptApi()
  238 + const data = (res && res.data) ? res.data : {}
  239 + this.purchaseDept = (data && typeof data === 'object') ? data : null
  240 + await this.loadRegionOptions()
  241 + } catch (e) {
  242 + this.purchaseDept = null
  243 + this.regionOptions = []
  244 + }
  245 + },
  246 + normalizeRegionOptions(raw) {
  247 + const list = Array.isArray(raw)
  248 + ? raw
  249 + : (Array.isArray(raw && raw.data) ? raw.data : (Array.isArray(raw && raw.rows) ? raw.rows : []))
  250 + return list.map(it => {
  251 + const id = it && (it.id != null ? it.id : (it.value != null ? it.value : (it.regionId != null ? it.regionId : '')))
  252 + const name = it && (it.name != null ? it.name : (it.label != null ? it.label : (it.regionName != null ? it.regionName : '')))
  253 + return { label: name != null ? String(name) : '', value: id != null ? String(id) : '' }
  254 + }).filter(it => it.value)
  255 + },
  256 + getOptionLabel(options, value) {
  257 + const v = value != null ? String(value) : ''
  258 + if (!v) return ''
  259 + const match = (options || []).find(o => String(o.value) === v)
  260 + return match ? String(match.label || '') : ''
  261 + },
  262 + getPurchaseDepartmentId() {
  263 + if (this.purchaseDept && this.purchaseDept.id != null) return String(this.purchaseDept.id)
  264 + const v = this.form && this.form.purchaseDepartment != null ? String(this.form.purchaseDepartment) : ''
  265 + return v || ''
  266 + },
  267 + async loadRegionOptions() {
  268 + const purchaseDepartment = this.getPurchaseDepartmentId()
  269 + if (!purchaseDepartment) {
  270 + this.regionOptions = []
  271 + return
  272 + }
  273 + try {
  274 + const res = await getAllRegionApi(purchaseDepartment)
  275 + const raw = res && res.data != null ? res.data : []
  276 + this.regionOptions = this.normalizeRegionOptions(raw)
  277 + } catch (e) {
  278 + this.regionOptions = []
  279 + }
  280 + },
  281 + dicToSheetOptions(items) {
  282 + const list = Array.isArray(items) ? items : []
  283 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  284 + },
  285 + handleButtonClick(btn) {
  286 + if (!btn || btn.disabled) return
  287 + if (typeof btn.onClick === 'function') return btn.onClick(this.form, btn.params)
  288 + const e = btn.event || ''
  289 + if (e === 'edit') return this.onEdit(btn && btn.params)
  290 + if (e === 'changeApply') return this.onChangeApply(btn && btn.params)
  291 + if (e === 'audit') return this.onAudit(btn && btn.params)
  292 + if (e === 'auditDetail') return this.onAuditDetail(btn && btn.params)
  293 + if (e === 'cancel') return this.onCancel(btn && btn.params)
  294 + },
  295 + onEdit(params) {
  296 + uni.navigateTo({ url: '/pages/domestic_trade/modify?id=' + this.id })
  297 + },
  298 + onChangeApply(params) {
  299 + uni.navigateTo({ url: '/pages/domestic_trade/change?id=' + this.id })
  300 + },
  301 + onAudit(params) {
  302 + const id = this.id || (this.form && this.form.id) || ''
  303 + if (!id) return
  304 + const CACHE_KEY = 'sourceBusinessId'
  305 + const TYPE = 'contractType'
  306 + uni.setStorageSync(TYPE, 'CUSTOMER_CREDIT_IN')
  307 + uni.setStorageSync(CACHE_KEY, id)
  308 + uni.navigateTo({ url: '/pages/flow/audit' })
  309 + },
  310 + onAuditDetail(params) {
  311 + const id = this.id || (this.form && this.form.id) || ''
  312 + if (!id) return
  313 + const CACHE_KEY = 'sourceBusinessId'
  314 + const TYPE = 'contractType'
  315 + uni.setStorageSync(TYPE, 'CUSTOMER_CREDIT_IN')
  316 + uni.setStorageSync(CACHE_KEY, id)
  317 + uni.navigateTo({ url: '/pages/flow/audit_detail' })
  318 + },
  319 + onCancel(params) {
  320 + const id = this.id || (this.form && this.form.id) || ''
  321 + if (!id) return
  322 + uni.showModal({
  323 + title: '系统提示',
  324 + content: '是否确定取消该流程?',
  325 + confirmText: '确定',
  326 + cancelText: '取消',
  327 + success: (res) => {
  328 + if (res && res.confirm) {
  329 + domesticCustomerCreditCancelApi(id).then(() => {
  330 + uni.showToast({ title: '已取消', icon: 'none' })
  331 + try { uni.setStorageSync('DOMESTIC_TRADE_LIST_NEED_REFRESH', '1') } catch (e) {}
  332 + setTimeout(() => { uni.redirectTo({ url: '/pages/domestic_trade/index' }) }, 300)
  333 + }).catch((e) => {
  334 + uni.showToast({ title: (e && e.msg) || '取消失败', icon: 'none' })
  335 + })
  336 + }
  337 + }
  338 + })
  339 + },
  340 + boolText(v) {
  341 + if (v === true) return '是'
  342 + if (v === false) return '否'
  343 + return '-'
  344 + },
  345 + safeText(v) {
  346 + const s = v == null ? '' : String(v)
  347 + return s.trim() ? s : ''
  348 + },
  349 + labelsOf(options, csv) {
  350 + const v = csv == null ? '' : String(csv)
  351 + if (!v) return '-'
  352 + const parts = v.split(',').filter(Boolean)
  353 + if (!parts.length) return '-'
  354 + const labels = []
  355 + ;(options || []).forEach(opt => {
  356 + const ov = opt && opt.value != null ? String(opt.value) : ''
  357 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  358 + })
  359 + return labels.filter(Boolean).join(',') || '-'
  360 + },
  361 + async loadDetail() {
  362 + this.loading = true
  363 + try {
  364 + const res = await domesticCustomerCreditGetApi(this.id)
  365 + const data = (res && res.data) ? res.data : {}
  366 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  367 + if (!data.investigatorName && data.investigatorId && u && String(u.id || '') === String(data.investigatorId || '')) {
  368 + data.investigatorName = u && u.name ? String(u.name) : ''
  369 + }
  370 + this.form = data
  371 + await this.loadRegionOptions()
  372 + } catch (e) {
  373 + this.form = {}
  374 + this.regionOptions = []
  375 + uni.showToast({ title: '详情加载失败', icon: 'none' })
  376 + } finally {
  377 + this.loading = false
  378 + }
  379 + },
  380 + onDownload(item) {
  381 + if (!item || !item.id) return
  382 + downloadFile(item.id, item.name || 'download')
  383 + }
  384 + }
  385 +}
  386 +</script>
  387 +
  388 +<style lang="scss" scoped>
  389 +.page {
  390 + display: flex;
  391 + flex-direction: column;
  392 + height: 100%;
  393 +}
  394 +
  395 +.scroll {
  396 + flex: 1;
  397 + padding: 8rpx 0 144rpx;
  398 +}
  399 +
  400 +.detail-page {
  401 + background: #f3f3f3;
  402 +}
  403 +
  404 +.title-header {
  405 + display: flex;
  406 + align-items: center;
  407 + padding: 24rpx 32rpx 12rpx;
  408 +
  409 + .title-header_icon {
  410 + width: 36rpx;
  411 + height: 36rpx;
  412 + margin-right: 12rpx;
  413 + }
  414 +
  415 + span {
  416 + font-size: 34rpx;
  417 + font-weight: 600;
  418 + color: rgba(0, 0, 0, 0.9);
  419 + }
  420 +}
  421 +
  422 +.section {
  423 + padding: 32rpx;
  424 + background: #fff;
  425 + margin-bottom: 20rpx;
  426 +}
  427 +
  428 +.row {
  429 + display: flex;
  430 + margin-bottom: 28rpx;
  431 +
  432 + &:last-child {
  433 + margin-bottom: 0;
  434 + }
  435 +
  436 + &.company {
  437 + font-size: 36rpx;
  438 + font-weight: 600;
  439 + color: rgba(0, 0, 0, 0.9);
  440 + padding-top: 8rpx;
  441 + line-height: 50rpx;
  442 + }
  443 +
  444 + .label {
  445 + max-width: 420rpx;
  446 + margin-right: 20rpx;
  447 + line-height: 32rpx;
  448 + font-size: 28rpx;
  449 + color: rgba(0, 0, 0, 0.6);
  450 + }
  451 +
  452 + .value {
  453 + flex: 1;
  454 + line-height: 32rpx;
  455 + font-size: 28rpx;
  456 + color: rgba(0, 0, 0, 0.9);
  457 + text-align: right;
  458 + word-break: break-all;
  459 +
  460 + &.act {
  461 + color: $theme-primary;
  462 + }
  463 +
  464 + &.pre {
  465 + white-space: pre-wrap;
  466 + }
  467 + }
  468 +}
  469 +.title-header {
  470 + background-color: #ffffff;
  471 +}
  472 +.file-item {
  473 + margin-bottom: 12rpx;
  474 +
  475 + &:last-child {
  476 + margin-bottom: 0;
  477 + }
  478 +}
  479 +</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(regionName) }}</text></view>
  77 + <view class="row"><text class="label">评审有效期</text><text class="value">{{ safeText(form.reviewValidUntil) }}</text></view>
  78 + <view class="row">
  79 + <text class="label">附件</text>
  80 + <view class="value">
  81 + <view v-if="!attachments.length" class="value">-</view>
  82 + <view v-for="item in attachments" :key="item.id || item.name" class="file-item" @click="onDownload(item)">
  83 + <text class="value act">{{ item.name }}</text>
  84 + </view>
  85 + </view>
  86 + </view>
  87 + </view>
  88 + </scroll-view>
  89 + </view>
  90 +</template>
  91 +
  92 +<script>
  93 +import { downloadFile } from '@/utils/downloadFile.js'
  94 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  95 +import { domesticCustomerCreditGetExamineByIdApi, getPurchaseDeptApi, getAllRegionApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  96 +
  97 +export default {
  98 + name: 'DomesticCustomerCreditViewer',
  99 + props: { id: { type: [String, Number], default: '' } },
  100 + data() {
  101 + return {
  102 + form: {},
  103 + dicOptions: {
  104 + COMPANY_NATURE: [],
  105 + DEVELOP_NEW: [],
  106 + OPERATION_METHOD: [],
  107 + PURCHASE_SOURCE: []
  108 + },
  109 + purchaseDept: null,
  110 + regionOptions: []
  111 + }
  112 + },
  113 + computed: {
  114 + attachments() {
  115 + const f = this.form || {}
  116 + const ids = f.attachmentFileIds != null ? String(f.attachmentFileIds) : ''
  117 + const names = f.attachmentFileNames != null ? String(f.attachmentFileNames) : ''
  118 + const idArr = ids ? ids.split(',').map(s => s.trim()).filter(Boolean) : []
  119 + const nameArr = names ? names.split(',') : []
  120 + if (idArr.length) {
  121 + return idArr.map((id, i) => ({ id, name: (nameArr[i] != null ? String(nameArr[i]) : '') }))
  122 + }
  123 + const legacy = Array.isArray(f.attachments) ? f.attachments : []
  124 + return legacy.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  125 + },
  126 + companyNatureOptions() {
  127 + return this.dicToSheetOptions(this.dicOptions.COMPANY_NATURE)
  128 + },
  129 + companyNatureName() {
  130 + return this.safeText(this.form.companyNatureName) || this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  131 + },
  132 + purchaseSourceName() {
  133 + const v = this.form && this.form.purchaseSource != null ? String(this.form.purchaseSource) : ''
  134 + return v ? getDicName('PURCHASE_SOURCE', v, this.dicOptions.PURCHASE_SOURCE) : '-'
  135 + },
  136 + operationModeName() {
  137 + const v = this.form && this.form.operationMode != null ? String(this.form.operationMode) : ''
  138 + return v ? getDicName('OPERATION_METHOD', v, this.dicOptions.OPERATION_METHOD) : '-'
  139 + },
  140 + isNewDevelopmentName() {
  141 + const v = this.form && this.form.isNewDevelopment != null ? String(this.form.isNewDevelopment) : ''
  142 + return v ? getDicName('DEVELOP_NEW', v, this.dicOptions.DEVELOP_NEW) : '-'
  143 + },
  144 + purchaseDepartmentName() {
  145 + if (this.purchaseDept && this.purchaseDept.name != null) return String(this.purchaseDept.name)
  146 + const v = this.form && this.form.purchaseDepartmentName != null ? String(this.form.purchaseDepartmentName) : ''
  147 + return v || '-'
  148 + },
  149 + regionName() {
  150 + const name = this.safeText(this.form && this.form.regionName)
  151 + if (name) return name
  152 + const id = this.form && this.form.region != null ? String(this.form.region) : ''
  153 + const labelFromOptions = this.getOptionLabel(this.regionOptions, id)
  154 + if (labelFromOptions) return labelFromOptions
  155 + return id || '-'
  156 + }
  157 + },
  158 + created() {
  159 + this.loadDicData()
  160 + this.loadPurchaseDeptOptions()
  161 + },
  162 + watch: {
  163 + id: {
  164 + immediate: true,
  165 + handler(val) {
  166 + const v = (val !== undefined && val !== null) ? String(val) : ''
  167 + if (v) this.loadDetail(v)
  168 + }
  169 + }
  170 + },
  171 + methods: {
  172 + async loadDicData() {
  173 + try {
  174 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  175 + this.dicOptions = {
  176 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  177 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  178 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  179 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  180 + }
  181 + } catch (e) {
  182 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  183 + }
  184 + },
  185 + async loadPurchaseDeptOptions() {
  186 + try {
  187 + const res = await getPurchaseDeptApi()
  188 + const data = (res && res.data) ? res.data : {}
  189 + this.purchaseDept = (data && typeof data === 'object') ? data : null
  190 + await this.loadRegionOptions()
  191 + } catch (e) {
  192 + this.purchaseDept = null
  193 + this.regionOptions = []
  194 + }
  195 + },
  196 + normalizeRegionOptions(raw) {
  197 + const list = Array.isArray(raw)
  198 + ? raw
  199 + : (Array.isArray(raw && raw.data) ? raw.data : (Array.isArray(raw && raw.rows) ? raw.rows : []))
  200 + return list.map(it => {
  201 + const id = it && (it.id != null ? it.id : (it.value != null ? it.value : (it.regionId != null ? it.regionId : '')))
  202 + const name = it && (it.name != null ? it.name : (it.label != null ? it.label : (it.regionName != null ? it.regionName : '')))
  203 + return { label: name != null ? String(name) : '', value: id != null ? String(id) : '' }
  204 + }).filter(it => it.value)
  205 + },
  206 + getOptionLabel(options, value) {
  207 + const v = value != null ? String(value) : ''
  208 + if (!v) return ''
  209 + const match = (options || []).find(o => String(o.value) === v)
  210 + return match ? String(match.label || '') : ''
  211 + },
  212 + getPurchaseDepartmentId() {
  213 + if (this.purchaseDept && this.purchaseDept.id != null) return String(this.purchaseDept.id)
  214 + const v = this.form && this.form.purchaseDepartment != null ? String(this.form.purchaseDepartment) : ''
  215 + return v || ''
  216 + },
  217 + async loadRegionOptions() {
  218 + const purchaseDepartment = this.getPurchaseDepartmentId()
  219 + if (!purchaseDepartment) {
  220 + this.regionOptions = []
  221 + return
  222 + }
  223 + try {
  224 + const res = await getAllRegionApi(purchaseDepartment)
  225 + const raw = res && res.data != null ? res.data : []
  226 + this.regionOptions = this.normalizeRegionOptions(raw)
  227 + } catch (e) {
  228 + this.regionOptions = []
  229 + }
  230 + },
  231 + dicToSheetOptions(items) {
  232 + const list = Array.isArray(items) ? items : []
  233 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  234 + },
  235 + labelsOf(options, csv) {
  236 + const v = csv == null ? '' : String(csv)
  237 + if (!v) return '-'
  238 + const parts = v.split(',').filter(Boolean)
  239 + if (!parts.length) return '-'
  240 + const labels = []
  241 + ;(options || []).forEach(opt => {
  242 + const ov = opt && opt.value != null ? String(opt.value) : ''
  243 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  244 + })
  245 + return labels.filter(Boolean).join(',') || '-'
  246 + },
  247 + boolText(v) {
  248 + if (v === true) return '是'
  249 + if (v === false) return '否'
  250 + return '-'
  251 + },
  252 + safeText(v) {
  253 + const s = v == null ? '' : String(v)
  254 + return s.trim() ? s : ''
  255 + },
  256 + async loadDetail(id) {
  257 + try {
  258 + const res = await domesticCustomerCreditGetExamineByIdApi(id)
  259 + this.form = (res && res.data) ? res.data : {}
  260 + await this.loadRegionOptions()
  261 + } catch (e) {
  262 + this.form = {}
  263 + this.regionOptions = []
  264 + }
  265 + },
  266 + onDownload(item) {
  267 + if (!item || !item.id) return
  268 + downloadFile(item.id, item.name || 'download')
  269 + }
  270 + }
  271 +}
  272 +</script>
  273 +
  274 +<style lang="scss" scoped>
  275 +.detail-page {
  276 + background: #f3f3f3;
  277 +}
  278 +
  279 +.scroll {
  280 + flex: 1;
  281 + padding: 8rpx 0 144rpx;
  282 +}
  283 +
  284 +.title-header {
  285 + display: flex;
  286 + align-items: center;
  287 + padding: 24rpx 32rpx 12rpx;
  288 + background-color: #ffffff;
  289 +
  290 + .title-header_icon {
  291 + width: 36rpx;
  292 + height: 36rpx;
  293 + margin-right: 12rpx;
  294 + }
  295 +
  296 + span {
  297 + font-size: 34rpx;
  298 + font-weight: 600;
  299 + color: rgba(0, 0, 0, 0.9);
  300 + }
  301 +}
  302 +
  303 +.section {
  304 + padding: 32rpx;
  305 + background: #fff;
  306 + margin-bottom: 20rpx;
  307 +}
  308 +
  309 +.row {
  310 + display: flex;
  311 + margin-bottom: 28rpx;
  312 +
  313 + &:last-child {
  314 + margin-bottom: 0;
  315 + }
  316 +
  317 + &.company {
  318 + font-size: 36rpx;
  319 + font-weight: 600;
  320 + color: rgba(0, 0, 0, 0.9);
  321 + padding-top: 8rpx;
  322 + line-height: 50rpx;
  323 + }
  324 +
  325 + .label {
  326 + max-width: 420rpx;
  327 + margin-right: 20rpx;
  328 + line-height: 32rpx;
  329 + font-size: 28rpx;
  330 + color: rgba(0, 0, 0, 0.6);
  331 + }
  332 +
  333 + .value {
  334 + flex: 1;
  335 + line-height: 32rpx;
  336 + font-size: 28rpx;
  337 + color: rgba(0, 0, 0, 0.9);
  338 + text-align: right;
  339 + word-break: break-all;
  340 +
  341 + &.act {
  342 + color: $theme-primary;
  343 + }
  344 +
  345 + &.pre {
  346 + white-space: pre-wrap;
  347 + }
  348 + }
  349 +}
  350 +
  351 +.file-item {
  352 + margin-bottom: 12rpx;
  353 +
  354 + &:last-child {
  355 + margin-bottom: 0;
  356 + }
  357 +}
  358 +</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 class="select-item" :class="form.purchaseDepartment ? 'is-filled' : 'is-empty'" clickable
  303 + @click="openSheet('purchaseDepartment')" :rightText="displayLabel('purchaseDepartmentName')" showArrow>
  304 + <template v-slot:body>
  305 + <view class="item-title"><text>采购处</text></view>
  306 + </template>
  307 + </uni-list-item>
  308 +
  309 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  310 + @click="openSheet('region')" :rightText="displayLabel('region')" showArrow>
  311 + <template v-slot:body>
  312 + <view class="item-title"><text>区域</text></view>
  313 + </template>
  314 + </uni-list-item>
  315 +
  316 + <uni-list-item title="评审有效期">
  317 + <template v-slot:footer>
  318 + <uni-datetime-picker type="date" v-model="form.reviewValidUntil" />
  319 + </template>
  320 + </uni-list-item>
  321 +
  322 + <uni-list-item class="mgb10" title="附件">
  323 + <template v-slot:footer>
  324 + <view class="attach-box">
  325 + <view v-for="(f, idx) in attachmentFiles" :key="idx" class="attach-row">
  326 + <FileUpload :value="f" @input="onAttachmentInput(idx, $event)" />
  327 + <text class="attach-del" @click.stop="removeAttachment(idx)">删除</text>
  328 + </view>
  329 + <view class="attach-row">
  330 + <FileUpload :value="newAttachment" @input="onAddAttachment" />
  331 + </view>
  332 + </view>
  333 + </template>
  334 + </uni-list-item>
  335 + </uni-list>
  336 + </scroll-view>
  337 +
  338 + <view class="footer">
  339 + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '保存中...' : '保存' }}</button>
  340 + </view>
  341 +
  342 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  343 + @confirm="onSheetConfirm" />
  344 + <MultiSelectSheet :visible.sync="multiSheet.visible" :title="multiSheet.title" :options="multiSheet.options"
  345 + v-model="multiSheet.value" @confirm="onMultiSheetConfirm" />
  346 + </view>
  347 +</template>
  348 +
  349 +<script>
  350 +import FileUpload from '@/components/file-upload/index.vue'
  351 +import SingleSelectSheet from '@/components/single-select/index.vue'
  352 +import MultiSelectSheet from '@/components/multi-select/index.vue'
  353 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  354 +import { domesticCustomerCreditGetApi, domesticCustomerCreditSaveApi, getPurchaseDeptApi, getAllRegionApi, getRegionApi } from '@/api/procure-manage/domesticCustomerCredit.js'
  355 +
  356 +export default {
  357 + name: 'DomesticTradeModify',
  358 + components: { FileUpload, SingleSelectSheet, MultiSelectSheet },
  359 + data() {
  360 + return {
  361 + id: '',
  362 + submitting: false,
  363 + loading: false,
  364 + newAttachment: { id: '', name: '' },
  365 + attachmentFiles: [],
  366 + sheet: { visible: false, title: '', options: [], field: '', value: '' },
  367 + multiSheet: { visible: false, title: '', options: [], field: '', value: '' },
  368 + dicOptions: {
  369 + COMPANY_NATURE: [],
  370 + DEVELOP_NEW: [],
  371 + OPERATION_METHOD: [],
  372 + PURCHASE_SOURCE: []
  373 + },
  374 + yesNoOptions: [
  375 + { label: '是', value: true },
  376 + { label: '否', value: false }
  377 + ],
  378 + companyNatureOptions: [],
  379 + operationMethodOptions: [],
  380 + developNewOptions: [],
  381 + purchaseSourceOptions: [],
  382 + regionOptions: [],
  383 + purchaseDeptOptions: [],
  384 + form: {
  385 + id: '',
  386 + unitName: '',
  387 + customerShortName: '',
  388 + companyNature: '',
  389 + companyNatureName: '',
  390 + companyNatureOther: '',
  391 + bankName: '',
  392 + bankAccount: '',
  393 + registeredCapital: '',
  394 + legalRepresentative: '',
  395 + companyEstablishedTime: '',
  396 + address: '',
  397 + businessPrincipal: '',
  398 + businessPrincipalPosition: '',
  399 + businessPrincipalPhone: '',
  400 + legalBusinessRelation: '',
  401 + factoryOfficeProperty: '',
  402 + factoryOfficeArea: '',
  403 + warehouseYardProperty: '',
  404 + warehouseYardArea: '',
  405 + mainEquipment: '',
  406 + normalInventory: '',
  407 + mainVarieties: '',
  408 + monthlyPurchaseVolume: '',
  409 + purchaseSource: '',
  410 + stockInProductName: '',
  411 + productName: '',
  412 + capacity: '',
  413 + salesChannel: '',
  414 + hasPreferentialPolicy: null,
  415 + investInFutures: null,
  416 + hasPenaltyRecord: null,
  417 + businessScopeMatch: null,
  418 + commonMaterialIssue: '',
  419 + otherIssue: '',
  420 + firstCooperationYear: '',
  421 + isNewDevelopment: '',
  422 + operationMode: '',
  423 + hasFailedPlanRecord: null,
  424 + hasPlanPerformanceIssue: null,
  425 + accountingProcess: '',
  426 + invoiceNameMatch: null,
  427 + outboundProcessStandard: null,
  428 + transportMode: '',
  429 + attachmentFileIds: '',
  430 + attachmentFileNames: '',
  431 + investigatorId: '',
  432 + investigatorName: '',
  433 + purchaseDepartment: '',
  434 + purchaseDepartmentName: '',
  435 + region: '',
  436 + regionName: '',
  437 + reviewValidUntil: ''
  438 + }
  439 + }
  440 + },
  441 + computed: {
  442 + showCompanyNatureOther() {
  443 + const v = String(this.form.companyNature || '')
  444 + return v.split(',').includes('OTHER')
  445 + }
  446 + },
  447 + async onLoad(query) {
  448 + const id = (query && (query.id || query.code)) ? String(query.id || query.code) : ''
  449 + this.id = id
  450 + await this.loadDicData()
  451 + await this.loadPurchaseDeptList()
  452 + await this.loadRegionOptions()
  453 + await this.loadDetail()
  454 + },
  455 + methods: {
  456 + async loadDicData() {
  457 + try {
  458 + const results = await getDicByCodes(['COMPANY_NATURE', 'DEVELOP_NEW', 'OPERATION_METHOD', 'PURCHASE_SOURCE'])
  459 + const next = {
  460 + COMPANY_NATURE: (results.COMPANY_NATURE && results.COMPANY_NATURE.data) || [],
  461 + DEVELOP_NEW: (results.DEVELOP_NEW && results.DEVELOP_NEW.data) || [],
  462 + OPERATION_METHOD: (results.OPERATION_METHOD && results.OPERATION_METHOD.data) || [],
  463 + PURCHASE_SOURCE: (results.PURCHASE_SOURCE && results.PURCHASE_SOURCE.data) || []
  464 + }
  465 + this.dicOptions = next
  466 + this.companyNatureOptions = this.dicToSheetOptions(next.COMPANY_NATURE)
  467 + this.developNewOptions = this.dicToSheetOptions(next.DEVELOP_NEW)
  468 + this.operationMethodOptions = this.dicToSheetOptions(next.OPERATION_METHOD)
  469 + this.purchaseSourceOptions = this.dicToSheetOptions(next.PURCHASE_SOURCE)
  470 + } catch (e) {
  471 + this.dicOptions = { COMPANY_NATURE: [], DEVELOP_NEW: [], OPERATION_METHOD: [], PURCHASE_SOURCE: [] }
  472 + this.companyNatureOptions = []
  473 + this.developNewOptions = []
  474 + this.operationMethodOptions = []
  475 + this.purchaseSourceOptions = []
  476 + uni.showToast({ title: '字典加载失败', icon: 'none' })
  477 + }
  478 + },
  479 + dicToSheetOptions(items) {
  480 + const list = Array.isArray(items) ? items : []
  481 + return list.map(it => ({ label: it && it.name != null ? String(it.name) : '', value: it && it.code != null ? String(it.code) : '' })).filter(it => it.value)
  482 + },
  483 + async loadPurchaseDeptList() {
  484 + try {
  485 + const res = await getPurchaseDeptApi()
  486 + const raw = res && res.data != null ? res.data : []
  487 + this.purchaseDeptOptions = this.normalizeRegionOptions(raw)
  488 + } catch (e) {
  489 + this.purchaseDeptOptions = []
  490 + }
  491 + },
  492 + normalizeRegionOptions(raw) {
  493 + const list = Array.isArray(raw)
  494 + ? raw
  495 + : (Array.isArray(raw && raw.data) ? raw.data : (Array.isArray(raw && raw.rows) ? raw.rows : []))
  496 + return list.map(it => {
  497 + const id = it && (it.id != null ? it.id : (it.value != null ? it.value : (it.regionId != null ? it.regionId : '')))
  498 + const name = it && (it.name != null ? it.name : (it.label != null ? it.label : (it.regionName != null ? it.regionName : '')))
  499 + return { label: name != null ? String(name) : '', value: id != null ? String(id) : '' }
  500 + }).filter(it => it.value)
  501 + },
  502 + getOptionLabel(options, value) {
  503 + const v = value != null ? String(value) : ''
  504 + if (!v) return ''
  505 + const match = (options || []).find(o => String(o.value) === v)
  506 + return match ? String(match.label || '') : ''
  507 + },
  508 + syncRegionWithOptions() {
  509 + const label = this.getOptionLabel(this.regionOptions, this.form.region)
  510 + if (!label) {
  511 + this.form.region = ''
  512 + this.form.regionName = ''
  513 + return
  514 + }
  515 + this.form.regionName = label
  516 + },
  517 + async loadRegionOptions() {
  518 + let defaultRegionId = ''
  519 + let defaultRegionName = ''
  520 + try {
  521 + const regionRes = await getRegionApi()
  522 + const regionData = (regionRes && regionRes.data != null) ? regionRes.data : null
  523 + const parsed = regionData ? this.parseRegionIdAndName(regionData) : { id: '', name: '' }
  524 + if (parsed.id) {
  525 + defaultRegionId = parsed.id
  526 + defaultRegionName = parsed.name
  527 + }
  528 + } catch (e) {
  529 + // fall through to getAllRegionApi
  530 + }
  531 + const purchaseDepartment = this.form.purchaseDepartment ? String(this.form.purchaseDepartment) : ''
  532 + if (!purchaseDepartment) {
  533 + if (defaultRegionId) {
  534 + this.regionOptions = [{ label: defaultRegionName || String(defaultRegionId), value: defaultRegionId }]
  535 + if (!this.form.region) {
  536 + this.form.region = defaultRegionId
  537 + this.form.regionName = defaultRegionName || String(defaultRegionId)
  538 + }
  539 + } else {
  540 + this.regionOptions = []
  541 + this.form.region = ''
  542 + this.form.regionName = ''
  543 + }
  544 + return
  545 + }
  546 + try {
  547 + const res = await getAllRegionApi(purchaseDepartment)
  548 + const raw = res && res.data != null ? res.data : []
  549 + this.regionOptions = this.normalizeRegionOptions(raw)
  550 + if (defaultRegionId) {
  551 + const label = this.getOptionLabel(this.regionOptions, defaultRegionId)
  552 + if (label) {
  553 + if (!this.form.region) {
  554 + this.form.region = defaultRegionId
  555 + this.form.regionName = label
  556 + }
  557 + } else {
  558 + // 默认区域不在完整列表中,仍保留为选中项
  559 + this.regionOptions.push({ label: defaultRegionName || String(defaultRegionId), value: defaultRegionId })
  560 + if (!this.form.region) {
  561 + this.form.region = defaultRegionId
  562 + this.form.regionName = defaultRegionName || String(defaultRegionId)
  563 + }
  564 + }
  565 + } else {
  566 + this.syncRegionWithOptions()
  567 + }
  568 + } catch (e) {
  569 + this.regionOptions = []
  570 + this.form.region = ''
  571 + this.form.regionName = ''
  572 + }
  573 + },
  574 + parseRegionIdAndName(raw) {
  575 + if (!raw) return { id: '', name: '' }
  576 + if (Array.isArray(raw)) return this.parseRegionIdAndName(raw[0])
  577 + if (typeof raw === 'string' || typeof raw === 'number') return { id: String(raw), name: '' }
  578 + const id = raw.id != null ? raw.id : (raw.value != null ? raw.value : (raw.regionId != null ? raw.regionId : ''))
  579 + const name = raw.name != null ? raw.name : (raw.label != null ? raw.label : (raw.regionName != null ? raw.regionName : ''))
  580 + return { id: id != null ? String(id) : '', name: name != null ? String(name) : '' }
  581 + },
  582 + displayLabel(field) {
  583 + const m = this.form
  584 + const map = {
  585 + purchaseDepartmentName: '请选择采购处',
  586 + companyNatureName: '请选择公司性质',
  587 + region: '请选择区域',
  588 + purchaseSource: '请选择',
  589 + operationMode: '请选择',
  590 + isNewDevelopment: '请选择',
  591 + hasPreferentialPolicy: '请选择',
  592 + investInFutures: '请选择',
  593 + hasPenaltyRecord: '请选择',
  594 + businessScopeMatch: '请选择',
  595 + hasFailedPlanRecord: '请选择',
  596 + hasPlanPerformanceIssue: '请选择',
  597 + invoiceNameMatch: '请选择',
  598 + outboundProcessStandard: '请选择'
  599 + }
  600 + if (field === 'companyNatureName') {
  601 + const val = m[field]
  602 + return val ? String(val) : map[field]
  603 + }
  604 + if (field === 'purchaseSource') {
  605 + const v = m.purchaseSource
  606 + return v ? getDicName('PURCHASE_SOURCE', String(v), this.dicOptions.PURCHASE_SOURCE) : map[field]
  607 + }
  608 + if (field === 'operationMode') {
  609 + const v = m.operationMode
  610 + return v ? getDicName('OPERATION_METHOD', String(v), this.dicOptions.OPERATION_METHOD) : map[field]
  611 + }
  612 + if (field === 'isNewDevelopment') {
  613 + const v = m.isNewDevelopment
  614 + return v ? getDicName('DEVELOP_NEW', String(v), this.dicOptions.DEVELOP_NEW) : map[field]
  615 + }
  616 + if (field === 'region') {
  617 + const v = m.region
  618 + if (!v) return map[field]
  619 + return this.getOptionLabel(this.regionOptions, v) || map[field]
  620 + }
  621 + if (field === 'purchaseDepartmentName') {
  622 + return this.getOptionLabel(this.purchaseDeptOptions, m.purchaseDepartment) || map[field]
  623 + }
  624 + const v = m[field]
  625 + if (v === true) return '是'
  626 + if (v === false) return '否'
  627 + return map[field] || '请选择'
  628 + },
  629 + openSheet(field) {
  630 + const map = {
  631 + region: { title: '区域', options: this.regionOptions },
  632 + purchaseDepartment: { title: '采购处', options: this.purchaseDeptOptions },
  633 + purchaseSource: { title: '收购来源', options: this.purchaseSourceOptions },
  634 + operationMode: { title: '操作方式', options: this.operationMethodOptions },
  635 + isNewDevelopment: { title: '是否新开发', options: this.developNewOptions },
  636 + hasPreferentialPolicy: { title: '是否享有优惠政策', options: this.yesNoOptions },
  637 + investInFutures: { title: '是否投资期货', options: this.yesNoOptions },
  638 + hasPenaltyRecord: { title: '是否有被处罚记录', options: this.yesNoOptions },
  639 + businessScopeMatch: { title: '实际经营范围与法定经营范围是否相符', options: this.yesNoOptions },
  640 + hasFailedPlanRecord: { title: '是否有计划落空的不良记录', options: this.yesNoOptions },
  641 + hasPlanPerformanceIssue: { title: '是否有计划履行不到位现象', options: this.yesNoOptions },
  642 + invoiceNameMatch: { title: '开票品名与出库单品名是否一致', options: this.yesNoOptions },
  643 + outboundProcessStandard: { title: '出库流程是否规范', options: this.yesNoOptions }
  644 + }
  645 + const cfg = map[field]
  646 + if (!cfg) return
  647 + const current = this.form[field]
  648 + const match = (cfg.options || []).find(o => String(o.value) === String(current))
  649 + this.sheet = {
  650 + ...this.sheet,
  651 + visible: true,
  652 + title: cfg.title,
  653 + options: cfg.options || [],
  654 + field,
  655 + value: match ? match.value : current
  656 + }
  657 + },
  658 + openMultiSheet(field) {
  659 + if (field !== 'companyNature') return
  660 + this.multiSheet = {
  661 + ...this.multiSheet,
  662 + visible: true,
  663 + title: '公司性质',
  664 + options: this.companyNatureOptions || [],
  665 + field,
  666 + value: this.form.companyNature || ''
  667 + }
  668 + },
  669 + onSheetConfirm({ value, label }) {
  670 + const field = this.sheet.field
  671 + if (!field) return
  672 + this.form[field] = value
  673 + if (field === 'region') this.form.regionName = label != null ? String(label) : this.getOptionLabel(this.regionOptions, value)
  674 + if (field === 'purchaseDepartment') {
  675 + this.form.purchaseDepartmentName = label != null ? String(label) : this.getOptionLabel(this.purchaseDeptOptions, value)
  676 + this.loadRegionOptions()
  677 + }
  678 + this.sheet.visible = false
  679 + },
  680 + onMultiSheetConfirm({ value }) {
  681 + const field = this.multiSheet.field
  682 + if (field === 'companyNature') {
  683 + const normalized = this.normalizeCompanyNature(value)
  684 + this.form.companyNature = normalized.value
  685 + this.form.companyNatureName = normalized.label
  686 + if (!this.showCompanyNatureOther) this.form.companyNatureOther = ''
  687 + }
  688 + this.multiSheet.visible = false
  689 + },
  690 + normalizeCompanyNature(valueStr) {
  691 + const selected = (valueStr ? String(valueStr).split(',').filter(Boolean) : [])
  692 + const finalSelected = selected.slice(0)
  693 + const orderedValues = []
  694 + const orderedLabels = []
  695 + ;(this.companyNatureOptions || []).forEach(opt => {
  696 + const v = opt && opt.value != null ? String(opt.value) : ''
  697 + if (v && finalSelected.includes(v)) {
  698 + orderedValues.push(v)
  699 + orderedLabels.push(opt.label != null ? String(opt.label) : '')
  700 + }
  701 + })
  702 + return { value: orderedValues.join(','), label: orderedLabels.join(',') }
  703 + },
  704 + removeAttachment(idx) {
  705 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  706 + list.splice(idx, 1)
  707 + this.attachmentFiles = list
  708 + },
  709 + onAddAttachment(val) {
  710 + const payload = val || { id: '', name: '' }
  711 + if (!payload.id) return
  712 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  713 + list.push(payload)
  714 + this.attachmentFiles = list
  715 + this.newAttachment = { id: '', name: '' }
  716 + },
  717 + onAttachmentInput(idx, val) {
  718 + const list = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.slice(0) : []
  719 + list[idx] = val || { id: '', name: '' }
  720 + this.attachmentFiles = list
  721 + },
  722 + validate() {
  723 + const requiredTextFields = [
  724 + { key: 'unitName', label: '单位名称' },
  725 + { key: 'customerShortName', label: '客户简称' },
  726 + { key: 'companyNature', label: '公司性质' },
  727 + { key: 'bankName', label: '开户行' },
  728 + { key: 'bankAccount', label: '账号' },
  729 + { key: 'legalRepresentative', label: '法人代表' },
  730 + { key: 'companyEstablishedTime', label: '公司成立时间' },
  731 + { key: 'address', label: '地址' },
  732 + { key: 'businessPrincipal', label: '业务负责人' },
  733 + { key: 'businessPrincipalPosition', label: '职务' },
  734 + { key: 'businessPrincipalPhone', label: '电话' },
  735 + { key: 'legalBusinessRelation', label: '法人与业务负责人关系' },
  736 + { key: 'factoryOfficeProperty', label: '生产厂房及办公楼产权' },
  737 + { key: 'factoryOfficeArea', label: '生产厂房及办公楼面积' },
  738 + { key: 'warehouseYardProperty', label: '仓库或货场产权' },
  739 + { key: 'warehouseYardArea', label: '仓库或货场产权面积' },
  740 + { key: 'mainEquipment', label: '主要生产设备' },
  741 + { key: 'normalInventory', label: '正常库存量' },
  742 + { key: 'mainVarieties', label: '主要品种' },
  743 + { key: 'monthlyPurchaseVolume', label: '月度收购量' },
  744 + { key: 'purchaseSource', label: '收购来源' },
  745 + { key: 'stockInProductName', label: '入库品名' },
  746 + { key: 'productName', label: '产品名称' },
  747 + { key: 'capacity', label: '产能' },
  748 + { key: 'salesChannel', label: '销售渠道' },
  749 + { key: 'firstCooperationYear', label: '首次合作年份' },
  750 + { key: 'isNewDevelopment', label: '是否新开发' },
  751 + { key: 'operationMode', label: '操作方式' },
  752 + { key: 'accountingProcess', label: '进销账务如何处理' },
  753 + { key: 'transportMode', label: '运输方式' },
  754 + { key: 'commonMaterialIssue', label: '常见料质问题' },
  755 + { key: 'otherIssue', label: '合作中的其它问题' },
  756 + { key: 'purchaseDepartment', label: '采购处' },
  757 + { key: 'reviewValidUntil', label: '评审有效期' },
  758 + { key: 'investigatorId', label: '资信调查人ID' }
  759 + ]
  760 + if (Array.isArray(this.regionOptions) && this.regionOptions.length) {
  761 + requiredTextFields.push({ key: 'region', label: '区域' })
  762 + }
  763 + for (let i = 0; i < requiredTextFields.length; i++) {
  764 + const f = requiredTextFields[i]
  765 + const v = this.form && this.form[f.key]
  766 + if (v == null || String(v).trim() === '') {
  767 + uni.showToast({ title: `${f.label}必填`, icon: 'none' })
  768 + return false
  769 + }
  770 + }
  771 +
  772 + const registeredCapital = Number(this.form.registeredCapital)
  773 + if (!Number.isFinite(registeredCapital) || registeredCapital < 0) {
  774 + uni.showToast({ title: '注册资金请填写数字', icon: 'none' })
  775 + return false
  776 + }
  777 +
  778 + const requiredBoolFields = [
  779 + { key: 'hasPreferentialPolicy', label: '是否享有优惠政策' },
  780 + { key: 'investInFutures', label: '是否投资期货' },
  781 + { key: 'hasPenaltyRecord', label: '是否有被处罚记录' },
  782 + { key: 'businessScopeMatch', label: '经营范围是否相符' },
  783 + { key: 'hasFailedPlanRecord', label: '计划落空不良记录' },
  784 + { key: 'hasPlanPerformanceIssue', label: '计划履行不到位现象' },
  785 + { key: 'invoiceNameMatch', label: '开票品名是否一致' },
  786 + { key: 'outboundProcessStandard', label: '出库流程是否规范' }
  787 + ]
  788 + for (let i = 0; i < requiredBoolFields.length; i++) {
  789 + const f = requiredBoolFields[i]
  790 + const v = this.form && this.form[f.key]
  791 + if (!(v === true || v === false)) {
  792 + uni.showToast({ title: `请选择${f.label}`, icon: 'none' })
  793 + return false
  794 + }
  795 + }
  796 +
  797 + const files = Array.isArray(this.attachmentFiles) ? this.attachmentFiles.filter(it => it && it.id) : []
  798 + if (!files.length) {
  799 + uni.showToast({ title: '请上传附件', icon: 'none' })
  800 + return false
  801 + }
  802 +
  803 + const phone = String(this.form.businessPrincipalPhone || '').trim()
  804 + if (phone && !/^1\d{10}$/.test(phone)) {
  805 + uni.showToast({ title: '电话请输入11位手机号', icon: 'none' })
  806 + return false
  807 + }
  808 + const year = String(this.form.firstCooperationYear || '').trim()
  809 + if (year && !/^\d{4}$/.test(year)) {
  810 + uni.showToast({ title: '首次合作年份请填写4位年份', icon: 'none' })
  811 + return false
  812 + }
  813 + return true
  814 + },
  815 + buildPayload() {
  816 + const payload = { ...this.form }
  817 + if (!this.showCompanyNatureOther) payload.companyNatureOther = ''
  818 + delete payload.companyNatureName
  819 + delete payload.investigatorName
  820 + delete payload.purchaseDepartmentName
  821 + delete payload.regionName
  822 + payload.registeredCapital = Number(payload.registeredCapital)
  823 + const files = (Array.isArray(this.attachmentFiles) ? this.attachmentFiles : []).filter(it => it && it.id)
  824 + payload.attachmentFileIds = files.map(it => String(it.id || '')).filter(Boolean).join(',')
  825 + payload.attachmentFileNames = files.map(it => String(it.name || '')).filter(Boolean).join(',')
  826 + return payload
  827 + },
  828 + async onSubmit() {
  829 + if (this.submitting) return
  830 + if (!this.validate()) return
  831 + this.submitting = true
  832 + const payload = this.buildPayload()
  833 + try {
  834 + await domesticCustomerCreditSaveApi(payload)
  835 + uni.showToast({ title: '保存成功', icon: 'success' })
  836 + setTimeout(() => { uni.redirectTo({ url: '/pages/domestic_trade/index' }) }, 300)
  837 + } catch (e) {
  838 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  839 + } finally {
  840 + this.submitting = false
  841 + }
  842 + },
  843 + async loadDetail() {
  844 + this.loading = true
  845 + try {
  846 + const res = await domesticCustomerCreditGetApi(this.id)
  847 + const data = res && res.data ? res.data : {}
  848 + const next = { ...this.form, ...(data || {}) }
  849 + next.id = next.id || this.id || ''
  850 + const u = (this.$store && this.$store.state && this.$store.state.user) ? this.$store.state.user : {}
  851 + if (!next.investigatorId) next.investigatorId = u && u.id ? String(u.id) : ''
  852 + if (!next.investigatorName) next.investigatorName = u && u.name ? String(u.name) : ''
  853 + this.form = next
  854 + this.syncRegionWithOptions()
  855 + this.form.companyNatureName = this.labelsOf(this.companyNatureOptions, this.form.companyNature)
  856 + this.attachmentFiles = this.normalizeAttachmentFiles(data || next)
  857 + } catch (e) {
  858 + uni.showToast({ title: '加载失败', icon: 'none' })
  859 + } finally {
  860 + this.loading = false
  861 + }
  862 + },
  863 + normalizeAttachmentFiles(raw) {
  864 + if (!raw) return []
  865 + const ids = raw.attachmentFileIds != null ? String(raw.attachmentFileIds) : ''
  866 + const names = raw.attachmentFileNames != null ? String(raw.attachmentFileNames) : ''
  867 + const idArr = ids ? ids.split(',').map(s => s.trim()).filter(Boolean) : []
  868 + const nameArr = names ? names.split(',') : []
  869 + if (idArr.length) {
  870 + return idArr.map((id, i) => ({ id, name: (nameArr[i] != null ? String(nameArr[i]) : '') }))
  871 + }
  872 + const legacy = Array.isArray(raw.attachments) ? raw.attachments : []
  873 + return legacy.filter(it => it && (it.id || it.name)).map(it => ({ id: it.id || '', name: it.name || '' }))
  874 + },
  875 + labelsOf(options, csv) {
  876 + const v = csv == null ? '' : String(csv)
  877 + if (!v) return ''
  878 + const parts = v.split(',').filter(Boolean)
  879 + if (!parts.length) return ''
  880 + const labels = []
  881 + ;(options || []).forEach(opt => {
  882 + const ov = opt && opt.value != null ? String(opt.value) : ''
  883 + if (ov && parts.includes(ov)) labels.push(opt.label != null ? String(opt.label) : '')
  884 + })
  885 + return labels.filter(Boolean).join(',') || ''
  886 + }
  887 + }
  888 +}
  889 +</script>
  890 +
  891 +<style lang="scss" scoped>
  892 +.page {
  893 + display: flex;
  894 + flex-direction: column;
  895 + height: 100%;
  896 +}
  897 +
  898 +.scroll {
  899 + flex: 1;
  900 + padding: 12rpx 0 160rpx;
  901 +}
  902 +
  903 +.footer {
  904 + position: fixed;
  905 + left: 0;
  906 + right: 0;
  907 + bottom: 0;
  908 + padding: 32rpx;
  909 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  910 + background: #fff;
  911 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  912 + z-index: 10;
  913 +
  914 + .btn {
  915 + height: 80rpx;
  916 + line-height: 80rpx;
  917 + border-radius: 12rpx;
  918 + font-size: 32rpx;
  919 + }
  920 +
  921 + .submit {
  922 + background: $theme-primary;
  923 + color: #fff;
  924 + }
  925 +}
  926 +
  927 +.title-header {
  928 + display: flex;
  929 + align-items: center;
  930 + padding: 24rpx 32rpx 12rpx;
  931 + background-color: #ffffff;
  932 + .title-header_icon {
  933 + width: 36rpx;
  934 + height: 36rpx;
  935 + margin-right: 12rpx;
  936 + }
  937 +
  938 + span {
  939 + font-size: 34rpx;
  940 + font-weight: 600;
  941 + color: rgba(0, 0, 0, 0.9);
  942 + }
  943 +}
  944 +
  945 +.mgb10 {
  946 + margin-bottom: 20rpx;
  947 +}
  948 +
  949 +.amount-row {
  950 + display: flex;
  951 + align-items: center;
  952 + gap: 12rpx;
  953 +
  954 + .unit, .prefix, .suffix {
  955 + font-size: 28rpx;
  956 + color: rgba(0, 0, 0, 0.6);
  957 + white-space: nowrap;
  958 + }
  959 +}
  960 +
  961 +.attach-box {
  962 + display: flex;
  963 + flex-direction: column;
  964 + align-items: flex-end;
  965 + gap: 16rpx;
  966 + width: 100%;
  967 +}
  968 +
  969 +.attach-row {
  970 + width: 100%;
  971 + display: flex;
  972 + justify-content: flex-end;
  973 + align-items: center;
  974 + gap: 20rpx;
  975 +}
  976 +
  977 +.attach-del {
  978 + font-size: 28rpx;
  979 + color: #D54941;
  980 +}
  981 +
  982 +::v-deep .uni-list {
  983 + .uni-easyinput {
  984 + display: flex;
  985 +
  986 + .uni-input-input {
  987 + color: rgba(0, 0, 0, 0.9);
  988 + }
  989 + }
  990 +
  991 + .uni-input-placeholder {
  992 + z-index: 1;
  993 + }
  994 +
  995 + .uni-input-input {
  996 + background-color: #ffffff;
  997 + }
  998 +
  999 + background: transparent;
  1000 +
  1001 + &-item {
  1002 + &__extra-text {
  1003 + font-size: 32rpx;
  1004 + }
  1005 +
  1006 + &__content-title {
  1007 + font-size: 32rpx;
  1008 + color: rgba(0, 0, 0, 0.9);
  1009 + }
  1010 +
  1011 + &__container {
  1012 + padding: 32rpx;
  1013 +
  1014 + .uni-easyinput {
  1015 + &__placeholder-class {
  1016 + font-size: 32rpx;
  1017 + color: rgba(0, 0, 0, 0.4);
  1018 + }
  1019 +
  1020 + &__content {
  1021 + border: none;
  1022 + background-color: #ffffff !important;
  1023 +
  1024 + &-input {
  1025 + padding-left: 0 !important;
  1026 + height: 48rpx;
  1027 + line-height: 48rpx;
  1028 + font-size: 32rpx;
  1029 + }
  1030 +
  1031 + .content-clear-icon {
  1032 + font-size: 44rpx !important;
  1033 + }
  1034 + }
  1035 + }
  1036 +
  1037 + .item-title,
  1038 + .uni-list-item__content {
  1039 + flex: none;
  1040 + min-height: 48rpx;
  1041 + line-height: 48rpx;
  1042 + font-size: 32rpx;
  1043 + position: relative;
  1044 + width: 210rpx;
  1045 + margin-right: 32rpx;
  1046 + color: rgba(0, 0, 0, 0.9);
  1047 +
  1048 + .required {
  1049 + color: red;
  1050 + position: absolute;
  1051 + top: 50%;
  1052 + transform: translateY(-50%);
  1053 + left: -16rpx;
  1054 + }
  1055 + }
  1056 + }
  1057 +
  1058 + &.select-item {
  1059 + &.is-empty {
  1060 + .uni-list-item__extra-text {
  1061 + color: rgba(0, 0, 0, 0.4) !important;
  1062 + }
  1063 + }
  1064 +
  1065 + &.is-filled {
  1066 + .uni-list-item__extra-text {
  1067 + color: rgba(0, 0, 0, 0.9) !important;
  1068 + }
  1069 + }
  1070 + }
  1071 +
  1072 + &.mgb10 {
  1073 + margin-bottom: 20rpx;
  1074 + }
  1075 + }
  1076 +}
  1077 +</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.redirectTo({ url: '/pages/foreign_trade/index' }) }, 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>
... ...