edit.vue 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. <template>
  2. <ion-page>
  3. <ion-header class="header-theme2">
  4. <ion-toolbar>
  5. <ion-buttons slot="start">
  6. <ion-icon :icon="arrowBackOutline" @click="onBack"></ion-icon>
  7. </ion-buttons>
  8. <ion-title>
  9. 企业信息录入
  10. </ion-title>
  11. </ion-toolbar>
  12. </ion-header>
  13. <ion-content>
  14. <div class="stepFlex">
  15. <div v-for="(record,key) in stepList" :key="key" class="stepFlex-item">
  16. <div
  17. :class="[(record.val < curStepData?.statusVal || curStepData?.statusVal == stepList.val) ? 'greenCircle' :record.val == curStepData?.statusVal ? 'now' : 'grayCircle']"></div>
  18. <div v-if="key !== stepList.length - 1"
  19. :class="[record.val < curStepData?.statusVal ? 'greenLine' : 'grayLine']"></div>
  20. <div class="stepFlex-item-label">
  21. <p class="stepFlex-item-label-title" @click="onRedirect(record.val)" >{{ record.title }}</p>
  22. <!--<p class="stepFlex-item-label-desc" @click="onRedirect(record.val)" >{{ record.desc }}</p>-->
  23. </div>
  24. </div>
  25. </div>
  26. <form autocomplete="off">
  27. <div class="bw-vue-form">
  28. <div class="form-title">基本项目</div>
  29. <div class="form-input">
  30. <ion-label>企业名称<span class="danger">*</span></ion-label>
  31. <div>
  32. <ion-input placeholder="请输入企业名称" label-placement="stacked" :style="{float: 'left',width:isAdd?'78%':'100%'}"
  33. @click="onOpenCompany" v-model="dataModel.companyName" class="custom" readonly >
  34. </ion-input>
  35. <ion-item v-if="isAdd" style="width:22%;float: right;padding:0px;margin: 0px;">
  36. <company-selection-like ref="refCompanySelectionLike" @resultInfo="onResultInfo"></company-selection-like>
  37. </ion-item>
  38. </div>
  39. <!-- <ion-label v-if="isAdd" style="float:right;width:80px;color:#02A5F0FF;position: relative;bottom:34px;left:14px;"-->
  40. <!-- @click="onGetFirmByCompanyName">同步</ion-label>-->
  41. <!-- <ion-note slot="error">企业名称不能为空</ion-note>-->
  42. </div>
  43. <div class="form-input">
  44. <ion-label>统一信用代码<span class="danger">*</span></ion-label>
  45. <ion-input placeholder="请输入统一信用代码或工商注册号" label-placement="stacked" :clear-input="true"
  46. v-model="dataModel.companyCode" class="custom">
  47. </ion-input>
  48. <!-- <ion-note slot="error">统一信用代码不能为空</ion-note>-->
  49. </div>
  50. <!-- <div class="form-select">-->
  51. <!-- <ion-label>所属驿站<span class="danger">*</span></ion-label>-->
  52. <!-- <ion-select disabled id="siteID" name="siteID" cancel-text="取消" v-model="dataModel.siteID"-->
  53. <!-- interface="action-sheet" placeholder="请选择所属驿站" style="width: 100%;text-align: left;">-->
  54. <!-- <ion-select-option v-for="(record,key) in siteList" :key="key" v-model:value="record.siteID">-->
  55. <!-- {{ record.siteName }}-->
  56. <!-- </ion-select-option>-->
  57. <!-- </ion-select>-->
  58. <!--&lt;!&ndash; <ion-note slot="error">服务驿站不能为空</ion-note>&ndash;&gt;-->
  59. <!-- </div>-->
  60. <ion-label style="padding-left: 10px;">所在街道/社区/镇村<span class="danger">*</span></ion-label>
  61. <div class="form-select">
  62. <ion-select disabled name="regionCode" id="regionCode" okText="确定" cancelText="取消" v-model="dataModel.regionCode"
  63. interface="action-sheet" placeholder="请选择市/县" style="width:50%;float:left;" @ionChange="changeCity()" >
  64. <ion-select-option v-for=" (it,key) in regionList" :key="key" :value="it.code">
  65. {{ it.name }}
  66. </ion-select-option>
  67. </ion-select>
  68. <ion-select interface="action-sheet" placeholder="请选择街道/社区/镇村" cancel-text="取消"
  69. id="streetCode" v-model="dataModel.streetCode" style="width: 50%;float: left;">
  70. <ion-select-option v-for="(record,key) in streetList" :key="key"
  71. v-model:value="record.code">
  72. {{ record.name }}
  73. </ion-select-option>
  74. </ion-select>
  75. </div>
  76. <div style="width: 100%;overflow: hidden;"></div>
  77. <div class="form-input">
  78. <ion-label>办公地址<span class="danger">*</span></ion-label>
  79. <ion-textarea placeholder="请输入办公地址" label-placement="stacked" :rows="3" :clear-input="true"
  80. v-model="dataModel.companyAddress" class="custom" style="border-bottom: 1px solid #fff2e8;">
  81. </ion-textarea>
  82. <!-- <ion-note slot="error">办公地址不能为空</ion-note>-->
  83. </div>
  84. <div class="form-input">
  85. <ion-label>企业联系人<span class="danger">*</span></ion-label>
  86. <ion-input placeholder="请输入企业联系人" label-placement="stacked" :clear-input="true"
  87. v-model="dataModel.userName" class="custom">
  88. </ion-input>
  89. <!-- <ion-note slot="error">企业联系人不能为空</ion-note>-->
  90. </div>
  91. <div class="form-input">
  92. <ion-label>联系电话<span class="danger">*</span></ion-label>
  93. <ion-input placeholder="请输入联系电话" label-placement="stacked" :clear-input="true"
  94. v-model="dataModel.userMobile" class="custom">
  95. </ion-input>
  96. <!-- <ion-note slot="error">企业联系电话不能为空</ion-note>-->
  97. </div>
  98. <div class="form-select">
  99. <ion-label>企业状态<span class="danger">*</span></ion-label>
  100. <ion-select id="recordStatus" name="recordStatus" cancel-text="取消" v-model="dataModel.recordStatus"
  101. interface="action-sheet" placeholder="请选择企业状态" style="width: 100%;text-align: left;">
  102. <ion-select-option v-for="(record,key) in companyStatusList" :key="key"
  103. v-model:value="record.value">
  104. {{ record.name }}
  105. </ion-select-option>
  106. </ion-select>
  107. <!-- <ion-note slot="error">企业状态不能为空</ion-note>-->
  108. </div>
  109. <div class="form-input">
  110. <ion-label>用工情况(人,含临时人员)<span class="danger">*</span></ion-label>
  111. <ion-input type="number" placeholder="请输入用工人数" label-placement="stacked" :clear-input="true"
  112. v-model="dataModel.workSituation" class="custom" @ionBlur="workSituationBlur">
  113. </ion-input>
  114. </div>
  115. <div class="form-title">
  116. 扩展项目
  117. <div style="float:right;">
  118. <ion-label style="color: red;font-size: 14px;" @click="isShow=!isShow">{{isShow?"收起":"展开"}}</ion-label>
  119. </div>
  120. </div>
  121. <div v-show="isShow" >
  122. <div class="form-select">
  123. <ion-label>是否缺工</ion-label>
  124. <ion-select id="isShortAge" name="isShortAge" cancel-text="取消" v-model="dataModel.isShortage"
  125. interface="action-sheet" placeholder="请选择是否缺工" style="width: 100%;text-align: left;">
  126. <ion-select-option v-for="(record,key) in shortAgeTypeList" :key="key"
  127. v-model:value="record.value">
  128. {{ record.name }}
  129. </ion-select-option>
  130. </ion-select>
  131. </div>
  132. <div class="form-input">
  133. <ion-label>法定代表人(负责人)</ion-label>
  134. <ion-input placeholder="请输入法定代表人" label-placement="stacked" :clear-input="true"
  135. v-model="dataModel.frName" class="custom">
  136. </ion-input>
  137. </div>
  138. <div class="form-input">
  139. <ion-label>营业执照有效期</ion-label>
  140. <div>
  141. <ion-radio v-model:checked="isLongDate" justify="start" labelPlacement="end"
  142. @click="changeLongDate" style="height:30px;">至长期</ion-radio>
  143. <ion-datetime-button datetime="validDate" style="position:relative;right:105px;"></ion-datetime-button>
  144. <ion-modal :keep-contents-mounted="true" >
  145. <ion-datetime id="validDate" name="validDate"
  146. v-model="dataModel.validDate" :prefer-wheel="true" @ionChange="changeValidDate"
  147. dataformatas="YYYY-MM-DD" presentation="date" cancel-text="取消" done-text="确定"
  148. :show-default-buttons="true" >
  149. </ion-datetime>
  150. </ion-modal>
  151. </div>
  152. </div>
  153. <div class="form-input">
  154. <ion-label>成立日期</ion-label>
  155. <ion-datetime-button datetime="establishmentTime" style="position:relative;right:110px;" ></ion-datetime-button>
  156. <ion-modal :keep-contents-mounted="true" >
  157. <ion-datetime id="establishmentTime" name="establishmentTime"
  158. v-model="dataModel.establishmentTime" :prefer-wheel="true"
  159. dataformatas="YYYY-MM-DD" presentation="date" cancel-text="取消" done-text="确定"
  160. :show-default-buttons="true" >
  161. </ion-datetime>
  162. </ion-modal>
  163. </div>
  164. <div class="form-input" >
  165. <ion-label>注册资本</ion-label>
  166. <div>
  167. <ion-input placeholder="请输入注册资本" label-placement="stacked" :clear-input="true"
  168. v-model="dataModel.registeredCapital" class="custom" style="width:60%;float:left;">
  169. </ion-input>
  170. <ion-select id="registeredCapitalType" name="registeredCapitalType" cancel-text="取消" v-model="dataModel.registeredCapitalType"
  171. interface="action-sheet" style="width: 40%;text-align: left;">
  172. <ion-select-option v-for="(record,key) in registeredCapitalTypeList" :key="key"
  173. v-model:value="record.value">
  174. {{ record.name }}
  175. </ion-select-option>
  176. </ion-select>
  177. </div>
  178. </div>
  179. <div class="form-select">
  180. <ion-label>企业注册地址行政区划</ion-label>
  181. <ion-select interface="action-sheet" placeholder="请选择" cancel-text="取消"
  182. id="signInPoliticalArea" v-model="dataModel.signInPoliticalArea"
  183. style="width: 100%;text-align: left;">
  184. <ion-select-option v-for="(record,key) in regionList" :key="key"
  185. v-model:value="record.code">
  186. {{ record.name }}
  187. </ion-select-option>
  188. </ion-select>
  189. </div>
  190. <div class="form-input" >
  191. <ion-label>企业邮箱</ion-label>
  192. <ion-input placeholder="请输入企业邮箱" label-placement="stacked" :clear-input="true"
  193. v-model="dataModel.companyEmail" class="custom">
  194. </ion-input>
  195. </div>
  196. <div class="form-select">
  197. <ion-label>经济类型</ion-label>
  198. <ion-select interface="action-sheet" placeholder="请选择经济类型" cancel-text="取消"
  199. id="companyType" v-model="dataModel.companyType" style="width: 100%;text-align: left;">
  200. <ion-select-option v-for="(record,key) in companyTypeList" :key="key"
  201. v-model:value="record.value">
  202. {{ record.name }}
  203. </ion-select-option>
  204. </ion-select>
  205. </div>
  206. <div class="form-input">
  207. <ion-label>所属行业</ion-label>
  208. <div>
  209. <ion-input placeholder="请选择所属行业" label-placement="stacked" style="float: left;width:78%;"
  210. v-model="dataModel.industryName" class="custom" readonly >
  211. </ion-input>
  212. <ion-item style="width:22%;float: right;padding:0px;margin: 0px;">
  213. <industry-selection :IndustryId="dataModel.industryID" @SetIndustryID="onSetIndustryID"></industry-selection>
  214. </ion-item>
  215. </div>
  216. <!-- <ion-select interface="action-sheet" placeholder="请选择所属行业" cancel-text="取消"-->
  217. <!-- id="professionID" v-model="dataModel.professionID" style="width: 100%;text-align: left;">-->
  218. <!-- <ion-select-option v-for="(record,key) in professionList" :key="key"-->
  219. <!-- v-model:value="record.value">-->
  220. <!-- {{ record.name }}-->
  221. <!-- </ion-select-option>-->
  222. <!-- </ion-select>-->
  223. </div>
  224. <div class="form-select">
  225. <ion-label>所属产业分类</ion-label>
  226. <ion-select interface="action-sheet" placeholder="请选择所属产业分类" cancel-text="取消"
  227. id="estateCategoryID" v-model="dataModel.estateCategoryID" style="width: 100%;text-align: left;">
  228. <ion-select-option v-for="(record,key) in estateCategoryList" :key="key"
  229. v-model:value="record.value">
  230. {{ record.name }}
  231. </ion-select-option>
  232. </ion-select>
  233. </div>
  234. <!-- <div class="form-select">-->
  235. <!-- <ion-label>企业标签</ion-label>-->
  236. <!-- <ion-select interface="action-sheet" placeholder="请选择企业标签" cancel-text="取消"-->
  237. <!-- id="tagID" v-model="dataModel.tagID" style="width: 100%;text-align: left;">-->
  238. <!-- <ion-select-option v-for="(record,key) in companyTagList" :key="key"-->
  239. <!-- v-model:value="record.value" style="width:100%;text-align: left;">-->
  240. <!-- {{ record.name }}-->
  241. <!-- </ion-select-option>-->
  242. <!-- </ion-select>-->
  243. <!-- </div>-->
  244. <div class="form-input">
  245. <ion-label>企业网站</ion-label>
  246. <ion-input placeholder="请输入企业网站" label-placement="stacked" :clear-input="true"
  247. v-model="dataModel.website" class="custom">
  248. </ion-input>
  249. </div>
  250. <div class="form-input">
  251. <ion-label>企业福利</ion-label>
  252. <ion-textarea placeholder="请输入企业福利" :rows="3" label-placement="stacked" :clear-input="true"
  253. v-model="dataModel.bonus" class="custom" style="border-bottom: 1px solid #fff2e8;">
  254. </ion-textarea>
  255. </div>
  256. <div class="form-select">
  257. <ion-label>企业规模</ion-label>
  258. <ion-select interface="action-sheet" placeholder="请选择企业规模" cancel-text="取消"
  259. id="companyModel" v-model="dataModel.companyModel" style="width: 100%;text-align: left;">
  260. <ion-select-option v-for="(record,key) in companyModelList" :key="key"
  261. v-model:value="record.value" style="width:100%;text-align: left;">
  262. {{ record.name }}
  263. </ion-select-option>
  264. </ion-select>
  265. </div>
  266. <div class="form-input">
  267. <ion-label>参保人数(人)</ion-label>
  268. <ion-input type="number" placeholder="请输入参保人数" label-placement="stacked" :clear-input="true"
  269. v-model="dataModel.insuredCount" class="custom" @ionBlur="insuredCountBlur">
  270. </ion-input>
  271. </div>
  272. <div class="form-input">
  273. <ion-label>经营范围</ion-label>
  274. <ion-textarea placeholder="请输入经营范围" :rows="3" label-placement="stacked" :clear-input="true"
  275. v-model="dataModel.businScope" class="custom" style="border-bottom: 1px solid #fff2e8;">
  276. </ion-textarea>
  277. </div>
  278. <div class="form-input">
  279. <ion-label>企业简介</ion-label>
  280. <ion-textarea placeholder="请输入企业简介" :rows="3" label-placement="stacked" :clear-input="true"
  281. v-model="dataModel.companyDesc" class="custom" style="border-bottom: 1px solid #fff2e8;">
  282. </ion-textarea>
  283. </div>
  284. <div class="form-input">
  285. <ion-label>标签</ion-label>
  286. <ion-row>
  287. <ion-col size="auto" v-for="(itemLabel,keyLabel) in dataModel.listLabel" :key="keyLabel">
  288. <ion-button color="primary" size="small">{{ itemLabel.labelName }}</ion-button>
  289. </ion-col>
  290. <ion-col>
  291. <ion-item style="float: right;padding:0px;margin: 0px;">
  292. <label-selection :key="'refLabelSelectionKey'" :ref="refLabelSelection" :big-type="1" :list-label="dataModel.listLabel"
  293. :title="'企业标签'" v-bind="$attrs" @resultBack="onResultBackLabels"></label-selection>
  294. <!-- <component :is="refLabelSelection" :big-type="1" :list-label="dataModel.listLabel" :title="'企业标签'"-->
  295. <!-- @resultBack="onResultBackLabels"></component>-->
  296. </ion-item>
  297. </ion-col>
  298. </ion-row>
  299. </div>
  300. </div>
  301. </div>
  302. </form>
  303. </ion-content>
  304. <ion-footer>
  305. <ion-toolbar>
  306. <ion-button style="width:100%;" @click="onNext">保存并下一步</ion-button>
  307. </ion-toolbar>
  308. </ion-footer>
  309. <ion-alert
  310. :is-open="alertingInfo"
  311. :header="infoAlterData.title"
  312. :message="infoAlterData.message"
  313. :buttons="infoAlertButtons"
  314. @didDismiss="setInfoAlertOpen(false)"
  315. ></ion-alert>
  316. <ion-loading
  317. :is-open="loadingFirm"
  318. message="正在同步企业信息..."
  319. @didDismiss="setInfoLoadingOpen(false)" >
  320. </ion-loading>
  321. </ion-page>
  322. </template>
  323. <script lang="ts">
  324. import {arrowBackOutline} from 'ionicons/icons';
  325. import {defineComponent, ref, reactive, computed, toRefs} from "vue";
  326. import {useRoute,useRouter} from "vue-router";
  327. import {alertController, onIonViewDidEnter} from "@ionic/vue";
  328. import {useVuelidate} from "@vuelidate/core";
  329. import {
  330. getCompanyById,
  331. getRegionList,
  332. getSiteList,
  333. getStreeList,
  334. normalFirm,
  335. saveCompany
  336. } from "@/api/company";
  337. import {required} from "@vuelidate/validators";
  338. import {getSysDictionaryList} from "@/api/system/dictionary";
  339. import dayjs from "dayjs";
  340. import IndustrySelection from "@/components/industrySelection.vue";
  341. import {getPosition} from "@/utils/position";
  342. import CompanySelectionLike from "@/components/companySelectionLike.vue";
  343. import LabelSelection from "@/components/labelSelection.vue";
  344. interface StepParams{
  345. name: string,
  346. statusVal: number,
  347. loginUserID: string
  348. }
  349. export default defineComponent({
  350. // name: 'CompanyEdit',
  351. components:{IndustrySelection,CompanySelectionLike, LabelSelection},
  352. setup() {
  353. const route = useRoute();
  354. const router = useRouter();
  355. const isAllowCommit = ref(true);
  356. const curStepData = ref<StepParams>({
  357. name:"",
  358. statusVal: 1,
  359. loginUserID:""
  360. });
  361. const isAdd = ref(false);
  362. const isShow = ref<any>(false);
  363. const loadingFirm = ref(false);
  364. // 信息弹窗内容
  365. const infoAlterData = reactive({
  366. title:"",
  367. message:""
  368. });
  369. const alertingInfo = ref(false);
  370. function setInfoAlertOpen(value: boolean) {
  371. alertingInfo.value = value;
  372. }
  373. function setInfoLoadingOpen(value: boolean) {
  374. loadingFirm.value = value;
  375. }
  376. const infoAlertButtons = [
  377. {
  378. text: '确定',
  379. role: 'confirm',
  380. handler: () => {
  381. setInfoAlertOpen(false);
  382. },
  383. },
  384. ];
  385. const isLongDate = ref<any>(false);
  386. const formState = reactive({
  387. dataModel: {
  388. companyID:null,
  389. companyCode: '',
  390. companyName: null,
  391. siteID: null,
  392. companyAddress: null,
  393. userName: null,
  394. userMobile: '',
  395. recordStatus: null,
  396. isShortage: null,
  397. frName: null,
  398. validDate: dayjs().format("YYYY-MM-DD"),
  399. establishmentTime: dayjs().format("YYYY-MM-DD"),
  400. registeredCapital:null,
  401. signInPoliticalArea:null,
  402. companyEmail: '',
  403. companyType: null,
  404. industryID:null,
  405. industryName:null,
  406. estateCategoryID: "",
  407. tagID:null,
  408. website:null,
  409. companyModel: 0,
  410. regionCode: null,
  411. streetCode: null,
  412. workSituation: null,
  413. insuredCount: null,
  414. businScope: null,
  415. companyDesc: null,
  416. longitude: null,
  417. latitude: null,
  418. listLabel: null
  419. }});
  420. const stepList = ref([
  421. {title: '基础信息', desc: '企业基础信息', val: 1},
  422. {title: '岗位信息', desc: '企业岗位信息', val: 3}
  423. ]);
  424. const companyStatusList = ref([]);
  425. const companyModelList = ref<any>([]);
  426. const companyTypeList = ref<any>([]);
  427. const companyTagList = ref<any>([]);
  428. const estateCategoryList = ref<any>([]);
  429. const regionList = ref<any>([]);
  430. const streetList = ref<any>([]);
  431. const siteList = ref<any>([]);
  432. const shortAgeTypeList = ref<any>([]);
  433. const registeredCapitalTypeList = ref<any>([]);
  434. const refCompanySelectionLike = ref();
  435. const refLabelSelection = ref();
  436. // /** 选择的区域 */
  437. // const regionChecked= ref<string>('');
  438. // // /** 选择的街道 */
  439. // const streetChecked= ref<string>('');
  440. //
  441. // // /** 编辑传入的地址 */
  442. // const defaultAddText= ref<string>('');
  443. //
  444. // const allData = ref<any>({
  445. // province: [],
  446. // city: [],
  447. // region: [{name:"",code:""}],
  448. // street: [{name:"",code:""}]
  449. // });
  450. //
  451. // //获取选定的省市区
  452. // const getCityArea = () =>{
  453. // // 城市选中后默认为字符串,并且获取到的是编码不是直接内容,为了把省份 城市 区域分为三个字段,所以把字符串分割为数组,在每个单独赋值
  454. // let cities = cityDefault.value.split(' ');
  455. // allData.value.province = provinceColumns.value;
  456. // allData.value.city = cityColumns.value;
  457. // allData.value.region = regionColumns.value[0].options;
  458. // allData.value.street = streetColumns.value[0].options;
  459. //
  460. // /* 循环城市数组,通过获取到的省市区编码来查询对应的文字内容 **/
  461. // allData.value.region.map(v=>{
  462. // if(v.code == cities[0]){
  463. // regionChecked.value = v.name; /* 县区 */
  464. // }
  465. // })
  466. // allData.value.street.map(v => {
  467. // if (v.code == cities[1]) {
  468. // streetChecked.value = v.name; /* 街道 */
  469. // }
  470. // })
  471. // }
  472. const getCompanyModelList = async function(){
  473. const companyModelResult :any = await getSysDictionaryList("CompanyModel");
  474. companyModelList.value = companyModelResult;
  475. }
  476. const getCompanyTagList = async function(){
  477. const companyTagResult :any = await getSysDictionaryList("CompanyTag");
  478. companyTagList.value = companyTagResult;
  479. }
  480. const getCompanyTypeList = async function(){
  481. const companyTypeResult :any = await getSysDictionaryList("CompanyType");
  482. companyTypeList.value = companyTypeResult;
  483. }
  484. const getCompanyStatusList = async function(){
  485. const companyStatusResult :any = await getSysDictionaryList("CompanyStatus");
  486. companyStatusList.value = companyStatusResult;
  487. }
  488. const getEstateCategoryList = async function(){
  489. const estateCategoryResult :any = await getSysDictionaryList("CompanyEstateCategory");
  490. estateCategoryList.value = estateCategoryResult;
  491. }
  492. const getShortAgeTypeList = async function(){
  493. const shortAgeTypeResult :any = await getSysDictionaryList("IsShortAge");
  494. shortAgeTypeList.value = shortAgeTypeResult;
  495. }
  496. const getRegisteredCapitalTypeList = async function(){
  497. const registeredCapitalTypeResult :any = await getSysDictionaryList("registeredCapitalType");
  498. registeredCapitalTypeList.value = registeredCapitalTypeResult;
  499. }
  500. function isStringInteger(value: string) {
  501. const n = parseInt(value, 10);
  502. return n.toString() === value && Number.isInteger(n);
  503. }
  504. function workSituationBlur() {
  505. inputValid.value = true;
  506. if (formState.dataModel.workSituation != null) {
  507. if(!isStringInteger(formState.dataModel.workSituation)||formState.dataModel.workSituation<1){
  508. presentAlert("用工情况必须为一个正整数!");
  509. inputValid.value = false;
  510. return;
  511. }
  512. // 匹配企业规模
  513. const workSituationRanges = [
  514. {max: 19, model: 1},
  515. {min: 20, max: 99, model: 2},
  516. {min: 100, max: 299, model: 3},
  517. {min: 300, max: 499, model: 4},
  518. {min: 500, max: 999, model: 5},
  519. {min: 1000, max: 9999, model: 6},
  520. {min: 10000, model: 7}
  521. ];
  522. const workSituation = formState.dataModel.workSituation;
  523. formState.dataModel.companyModel = 1; // 默认值,如果所有范围都不匹配
  524. for (const range of workSituationRanges) {
  525. if (
  526. (range.min === undefined || workSituation >= range.min) &&
  527. (range.max === undefined || workSituation <= range.max)
  528. ) {
  529. formState.dataModel.companyModel = range.model;
  530. break;
  531. }
  532. }
  533. }
  534. }
  535. function insuredCountBlur() {
  536. inputValid.value = true;
  537. if (formState.dataModel.insuredCount != null) {
  538. if(!isStringInteger(formState.dataModel.insuredCount)||formState.dataModel.insuredCount<1){
  539. presentAlert("参保人数必须为一个正整数!");
  540. inputValid.value = false;
  541. }
  542. }
  543. }
  544. const rules = computed(() => {
  545. return {
  546. dataModel: {
  547. companyCode: {required},
  548. companyName: {required},
  549. // siteID: {required},
  550. companyAddress: {required},
  551. userName: {required},
  552. userMobile: {required},
  553. recordStatus: {required},
  554. workSituation: {required},
  555. }
  556. }
  557. });
  558. const v$ = useVuelidate(rules, formState);
  559. const changeLongDate = ()=>{
  560. isLongDate.value = true;
  561. formState.dataModel.validDate = "2099-12-31T00:00:00.000+08:00";
  562. };
  563. const changeValidDate = () => {
  564. isLongDate.value = false;
  565. };
  566. const companyCodeValidate = ()=>{
  567. isAllowCommit.value = true;
  568. const codeReg = /^[0-9A-Z]+$/;
  569. const gsCodeReg = /^\d{15}$/;
  570. if (formState.dataModel.companyCode.length != 18 && formState.dataModel.companyCode.length != 15) {
  571. presentAlert('输入的统一信用代码无效!');
  572. isAllowCommit.value = false;
  573. return;
  574. }
  575. if (formState.dataModel.companyCode.length == 15) {
  576. if (!gsCodeReg.test(formState.dataModel.companyCode)) {
  577. presentAlert('输入的工商注册号有误!');
  578. isAllowCommit.value = false;
  579. }
  580. }
  581. if (formState.dataModel.companyCode.length == 18) {
  582. if (!codeReg.test(formState.dataModel.companyCode)) {
  583. presentAlert('输入的统一信用代码无效!');
  584. isAllowCommit.value = false;
  585. } else {
  586. let aCode;
  587. let aCodeValue;
  588. let total = 0;
  589. const weightedFactors = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
  590. const str = '0123456789ABCDEFGHJKLMNPQRTUWXY';
  591. for (let i = 0; i < formState.dataModel.companyCode.length - 1; i++) {
  592. aCode = formState.dataModel.companyCode.substring(i, i + 1);
  593. aCodeValue = str.indexOf(aCode);
  594. total += aCodeValue * weightedFactors[i];
  595. }
  596. let logicCheckCode = 31 - total % 31;
  597. if (logicCheckCode == 31) {
  598. logicCheckCode = 0;
  599. }
  600. const Str = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y";
  601. const Array_Str = Str.split(',');
  602. const correctCodeStr = Array_Str[logicCheckCode];
  603. console.log("正确的校验码是", correctCodeStr);
  604. const currentCodeStr = formState.dataModel.companyCode.substring(17, 18);
  605. if (correctCodeStr != currentCodeStr) {
  606. presentAlert('输入的统一信用代码无效!');
  607. isAllowCommit.value = false;
  608. }
  609. }
  610. }
  611. }
  612. const inputDataValidate = () =>{
  613. const mobileReg = /^1[3|4|5|6|7|8|9]\d{9}$/;
  614. // const landlineReg = /[0-9-()()]{7,18}/;
  615. const landlineReg = /^((0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/;
  616. if(!mobileReg.test(formState.dataModel.userMobile)&&!landlineReg.test(formState.dataModel.userMobile)){
  617. presentAlert("输入的联系电话有误!");
  618. isAllowCommit.value = false;
  619. }
  620. const emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
  621. // 这里由于企业邮箱非必填所以先判断是否填写了企业邮箱
  622. if(formState.dataModel.companyEmail!=null&&formState.dataModel.companyEmail!=""){
  623. if(!emailReg.test(formState.dataModel.companyEmail)){
  624. presentAlert("输入的企业邮箱有误!");
  625. isAllowCommit.value = false;
  626. }
  627. }
  628. };
  629. const onGetFirmByCompanyName = async function() {
  630. if(formState.dataModel.companyName){
  631. await setInfoLoadingOpen(true);
  632. let matchedFirmInfo :any = await normalFirm(formState.dataModel.companyName);
  633. if(matchedFirmInfo){
  634. await setInfoLoadingOpen(false);
  635. infoAlterData.title = "提示";
  636. infoAlterData.message = "同步成功!";
  637. await setInfoAlertOpen(true);
  638. }else{
  639. matchedFirmInfo = {};
  640. await setInfoLoadingOpen(false);
  641. infoAlterData.title = "错误";
  642. infoAlterData.message = "查找不到该企业,请核实企业名称是否正确!";
  643. await setInfoAlertOpen(true);
  644. }
  645. formState.dataModel.frName = matchedFirmInfo.frName;
  646. formState.dataModel.registeredCapital = matchedFirmInfo.registeredCapital;
  647. formState.dataModel.companyCode = matchedFirmInfo.companyCode;
  648. formState.dataModel.insuredCount = matchedFirmInfo.insuredCount;
  649. formState.dataModel.userMobile = matchedFirmInfo.userMobile;
  650. formState.dataModel.companyEmail = matchedFirmInfo.companyEmail;
  651. formState.dataModel.companyAddress = matchedFirmInfo.companyAddress;
  652. formState.dataModel.businScope = matchedFirmInfo.businScope;
  653. formState.dataModel.industryID = matchedFirmInfo.industryID;
  654. formState.dataModel.industryName = matchedFirmInfo.industryName;
  655. setEstateCategoryID(matchedFirmInfo.industryName);
  656. formState.dataModel.signInPoliticalArea = matchedFirmInfo.signInPoliticalArea;
  657. formState.dataModel.establishmentTime = matchedFirmInfo.establishmentTime;
  658. }else{
  659. infoAlterData.title = "提示";
  660. infoAlterData.message = "请输入企业名称!";
  661. await setInfoAlertOpen(true);
  662. }
  663. }
  664. const onSetIndustryID = (data: any)=>{
  665. formState.dataModel.industryID = data.value;
  666. formState.dataModel.industryName = data.text;
  667. const text = data.text.split("-")[0] as string;
  668. setEstateCategoryID(text)
  669. }
  670. function setEstateCategoryID(industryName: any) {
  671. // 所属产业判断
  672. const categoryMap: { [key: string]: any } = {
  673. '农、林、牧、渔业': 1,
  674. '采矿业': 2,
  675. '制造业': 2,
  676. '电力、热力、燃气及水生产和供应业': 2,
  677. '建筑业': 2
  678. };
  679. if (industryName) {
  680. formState.dataModel.estateCategoryID = categoryMap[industryName] || 3;
  681. } else {
  682. formState.dataModel.estateCategoryID = "3";
  683. }
  684. }
  685. const inputValid = ref(true);
  686. const onNext = async () => {
  687. console.log(formState.dataModel)
  688. const isFormCorrect = await v$.value.$validate();
  689. if (!isFormCorrect) {
  690. await presentAlert('请输入完整信息!');
  691. return null;
  692. }
  693. companyCodeValidate();
  694. inputDataValidate();
  695. if(isAllowCommit.value&&inputValid.value){
  696. saveCompany(formState.dataModel).then(result => {
  697. if (result) {
  698. router.push({path: './postList', query: {reload:1,id:formState.dataModel.companyID,status:3,isEdit:isAdd.value!=true?1:0,random:Math.random()}});
  699. }
  700. });
  701. }
  702. };
  703. const onResultBackLabels = (data: any) => {
  704. formState.dataModel.listLabel = data;
  705. refLabelSelection.value = null;
  706. }
  707. const onResultInfo = (data: any)=>{
  708. formState.dataModel.companyName = data.text;
  709. onGetFirmByCompanyName();
  710. }
  711. const onOpenCompany = () => {
  712. if(!isAdd.value){
  713. return;
  714. }
  715. refCompanySelectionLike.value.onOpen();
  716. }
  717. const onBack = () => {
  718. router.push({path: './list', query: {reload:1}});
  719. }
  720. const onRedirect = (statusValue:any) => {
  721. if(!isAdd.value && statusValue==3) {
  722. router.push({path: './postList', query: {reload:1,id:formState.dataModel.companyID,status:3,isEdit:1,random:Math.random()}});
  723. }
  724. }
  725. const getRegionListData = () => {
  726. getRegionList({}).then(data => {
  727. regionList.value = data;
  728. });
  729. }
  730. const getStreetListData = (code: any) => {
  731. getStreeList({code: code}).then(data => {
  732. streetList.value = data;
  733. });
  734. }
  735. const getSiteListData = () => {
  736. getSiteList({}).then(data => {
  737. siteList.value = data;
  738. });
  739. }
  740. const changeCity = () => {
  741. if (formState.dataModel.regionCode)
  742. getStreetListData(formState.dataModel.regionCode);
  743. }
  744. const loadData = async (companyID: any,status:any,loginUserId:any) => {
  745. curStepData.value.statusVal = status;
  746. curStepData.value.loginUserID = loginUserId;
  747. isAdd.value = companyID == null;
  748. const reqData = await getCompanyById(companyID,loginUserId);
  749. formState.dataModel = reqData;
  750. isLongDate.value = formState.dataModel.validDate == "2099-12-31T00:00:00.000+08:00";
  751. console.log('dataModel',formState.dataModel);
  752. if(formState.dataModel.regionCode!=null) getStreetListData(formState.dataModel.regionCode);
  753. if (companyID == null) {
  754. setLongitudeLatitude();
  755. }
  756. };
  757. /* watch(() => route.query, () => {
  758. if (route.query.reload) {
  759. loadData(route.query.id,route.query.status);
  760. }
  761. });*/
  762. const reload = (companyID:any,status:any,loginUserId:any) => {
  763. isShow.value = false;
  764. loadData(companyID,status,loginUserId);
  765. }
  766. onIonViewDidEnter(() => {
  767. if (route.query.reload) {
  768. reload(route.query.id,route.query.status,route.query.loginUserID);
  769. }
  770. });
  771. const presentAlert = async (message: string) => {
  772. const alert = await alertController.create({
  773. header: '错误!',
  774. message: message,
  775. buttons: [
  776. '确定'
  777. ],
  778. });
  779. await alert.present();
  780. }
  781. // 设置经纬度
  782. function setLongitudeLatitude() {
  783. getPosition().then((data: any) => {
  784. if (data.longitude != null && data.latitude != null) {
  785. formState.dataModel.longitude = data.longitude;
  786. formState.dataModel.latitude = data.latitude;
  787. }
  788. })
  789. }
  790. return {
  791. ...toRefs(formState),
  792. arrowBackOutline,
  793. route,
  794. router,
  795. isAdd,
  796. isShow,
  797. v$,
  798. refCompanySelectionLike,
  799. onOpenCompany,
  800. onResultInfo,
  801. refLabelSelection,
  802. onResultBackLabels,
  803. isLongDate,
  804. curStepData,
  805. stepList,
  806. companyTypeList,
  807. siteList,
  808. regionList,
  809. streetList,
  810. shortAgeTypeList,
  811. registeredCapitalTypeList,
  812. companyStatusList,
  813. companyModelList,
  814. companyTagList,
  815. estateCategoryList,
  816. infoAlertButtons,
  817. infoAlterData,
  818. alertingInfo,
  819. loadingFirm,
  820. workSituationBlur,
  821. insuredCountBlur,
  822. setInfoAlertOpen,
  823. setInfoLoadingOpen,
  824. onGetFirmByCompanyName,
  825. onSetIndustryID,
  826. onNext,
  827. onBack,
  828. onRedirect,
  829. getCompanyStatusList,
  830. getCompanyModelList,
  831. getCompanyTypeList,
  832. getCompanyTagList,
  833. getEstateCategoryList,
  834. getShortAgeTypeList,
  835. getRegisteredCapitalTypeList,
  836. getRegionListData,
  837. getSiteListData,
  838. changeCity,
  839. changeLongDate,
  840. changeValidDate,
  841. loadData,
  842. }
  843. },mounted(){
  844. this.getCompanyModelList();
  845. this.getCompanyTypeList();
  846. this.getCompanyTagList();
  847. this.getCompanyStatusList();
  848. this.getEstateCategoryList();
  849. this.getShortAgeTypeList();
  850. this.getRegisteredCapitalTypeList();
  851. this.getRegionListData();
  852. this.getSiteListData();
  853. }
  854. });
  855. </script>
  856. <style lang="less">
  857. ion-select#siteID.md.select-disabled.legacy-select::after{display: none;}
  858. ion-select#regionCode.md.select-disabled.legacy-select::after{display: none;}
  859. .custom{
  860. --placeholder-color: gray;
  861. --placeholder-opacity: 0.5;
  862. }
  863. .title-item{
  864. margin-left: 15px;
  865. color:#1c3d70 !important;
  866. font-size: 14px !important;
  867. font-weight: bold;
  868. }
  869. ion-item {
  870. --border-width: 0;
  871. --border-style: none;
  872. ion-label, ion-input, ion-select, ion-datetime-button {
  873. font-size: 14px !important;
  874. }
  875. }
  876. .stepFlex {
  877. margin: 0;
  878. display: flex;
  879. width: 100%;
  880. .stepFlex-item {
  881. position: relative;
  882. flex: 1;
  883. text-align: center;
  884. margin-top: -10px;
  885. .stepFlex-item-label {
  886. padding-top: 30px;
  887. font-size: 14px;
  888. .stepFlex-item-label-title {
  889. margin-top: 30px;
  890. }
  891. .stepFlex-item-label-desc {
  892. margin-top: 5px;
  893. color: #b9b9bd;
  894. }
  895. }
  896. }
  897. .greenCircle {
  898. top: calc(50% - 15px);
  899. left: calc(50% - 4px);
  900. position: absolute;
  901. z-index: 2;
  902. width: 10px;
  903. height: 10px;
  904. border-radius: 50%;
  905. background-color: #31A2FE;
  906. }
  907. .now {
  908. top: calc(50% - 18px);
  909. left: calc(50% - 8px);
  910. position: absolute;
  911. z-index: 3;
  912. width: 16px;
  913. height: 16px;
  914. border-radius: 50%;
  915. background-color: #31A2FE;
  916. border: 4px solid #c5e8f9;
  917. }
  918. .grayCircle {
  919. top: calc(50% - 15px);
  920. left: calc(50% - 4px);
  921. position: absolute;
  922. z-index: 2;
  923. width: 10px;
  924. height: 10px;
  925. border-radius: 50%;
  926. background-color: #ccc;
  927. }
  928. .greenLine {
  929. width: 100%;
  930. top: calc(50% - 11px);
  931. left: calc(50% - 2px);
  932. height: 2px;
  933. background-color: #31A2FE;
  934. position: absolute;
  935. }
  936. .grayLine {
  937. height: 0;
  938. border: 1px dashed #ccc;
  939. width: 100%;
  940. top: calc(50% - 11px);
  941. left: calc(50% - 2px);
  942. position: absolute;
  943. }
  944. }
  945. </style>