VerifyDevice.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <script setup lang="ts">
  2. import { computed, ref, watch } from 'vue';
  3. import SvgIcon from '@/components/SvgIcon.vue';
  4. import { useRequest } from '@/hooks/request';
  5. import { t } from '@/i18n';
  6. import { getGatewayModelInfo, orgGatewayRegister, validateGatewayInfo } from '@/api';
  7. import deviceCard1 from '@/assets/img/device-card1.png';
  8. import deviceCard2 from '@/assets/img/device-card2.png';
  9. import deviceCard3 from '@/assets/img/device-card3.png';
  10. import deviceCard4 from '@/assets/img/device-card4.png';
  11. import deviceLabel from '@/assets/img/device-label.png';
  12. import deviceManual from '@/assets/img/device-manual.png';
  13. import type { FormInstance, Rule } from 'ant-design-vue/es/form';
  14. import type { InterfaceNum, RegisterGatewayForm, UseGuideStepItemExpose, UseGuideStepItemProps } from '@/types';
  15. const props = defineProps<UseGuideStepItemProps<RegisterGatewayForm>>();
  16. const currentStep = props.steps[props.stepIndex];
  17. const formRef = ref<FormInstance>();
  18. const rules: Record<string, Rule[]> = {
  19. snCode: [
  20. {
  21. required: true,
  22. message: t('registerGateway.pleaseSnCode'),
  23. trigger: 'change',
  24. },
  25. ],
  26. password: [
  27. {
  28. required: true,
  29. message: t('registerGateway.pleasePassword'),
  30. trigger: 'change',
  31. },
  32. ],
  33. };
  34. const { handleRequest } = useRequest();
  35. const interfaceNum = computed<InterfaceNum | undefined>(() => {
  36. const { interfaceNum } = props.form;
  37. return interfaceNum === '' ? undefined : JSON.parse(interfaceNum);
  38. });
  39. const verificationGateway = () => {
  40. formRef.value
  41. ?.validate()
  42. .then(() => {
  43. handleRequest(async () => {
  44. const { modelId, state, id } = await validateGatewayInfo({
  45. snCode: props.form.snCode,
  46. password: props.form.password,
  47. });
  48. props.form.modelId = modelId;
  49. props.form.id = id;
  50. Object.assign(props.form, {
  51. modelId,
  52. state,
  53. id,
  54. });
  55. props.form.show = true;
  56. currentStep.nextStepButtonDisabled = false;
  57. if (props.form.modelId) {
  58. const { docUrl, iconUrl, interfaceNum, modelName, surfMode, surfModeEn } = await getGatewayModelInfo(
  59. props.form.modelId,
  60. );
  61. Object.assign(props.form, {
  62. docUrl,
  63. iconUrl,
  64. interfaceNum,
  65. modelName,
  66. surfMode: JSON.parse(surfMode),
  67. surfModeEn,
  68. });
  69. }
  70. });
  71. props.form.show = false;
  72. })
  73. .catch(() => {});
  74. };
  75. const productManual = () => {
  76. const fileUrl = import.meta.env.VITE_IMG_API + props.form.docUrl; // 替换为你的文件URL
  77. window.open(fileUrl, '_blank');
  78. };
  79. const ternaryExpression = (value: boolean) => {
  80. if (value) {
  81. return props.form.state === 1 ? t('common.online') : t('common.offline');
  82. } else {
  83. return props.form.state === 1 ? 'background-color: #52C41A;' : 'background-color: #666666;';
  84. }
  85. };
  86. const finish = () => {
  87. if (!props.form.judgmentRegistration) {
  88. handleRequest(async () => {
  89. await orgGatewayRegister(props.form.id);
  90. props.form.judgmentRegistration = true;
  91. });
  92. }
  93. };
  94. defineExpose<UseGuideStepItemExpose>({
  95. finish,
  96. });
  97. watch(
  98. () => props.form.snCode,
  99. (count) => {
  100. if (count) {
  101. if (props.form.show) {
  102. currentStep.nextStepButtonDisabled = true;
  103. props.form.show = false;
  104. }
  105. }
  106. },
  107. );
  108. watch(
  109. () => props.form.password,
  110. (count) => {
  111. if (count) {
  112. if (props.form.show) {
  113. currentStep.nextStepButtonDisabled = true;
  114. props.form.show = false;
  115. }
  116. }
  117. },
  118. );
  119. const imgUrl = computed(() => {
  120. return import.meta.env.VITE_IMG_API + props.form.iconUrl;
  121. });
  122. </script>
  123. <template>
  124. <div>
  125. <ARow>
  126. <ACol :span="5">
  127. <AForm ref="formRef" :model="form" label-align="left" :rules="rules" :label-col="{ span: 6 }">
  128. <AFormItem :label="$t('registerGateway.snCode')" name="snCode">
  129. <AInput :placeholder="$t('common.pleaseEnter')" v-model:value="form.snCode" />
  130. </AFormItem>
  131. <AFormItem :label="$t('registerGateway.devicePassword')" name="password">
  132. <AInput v-model:value="form.password" :placeholder="$t('common.pleaseEnter')" />
  133. </AFormItem>
  134. <AFormItem>
  135. <AButton class="dev-but icon-button" type="primary" @click="verificationGateway">
  136. <SvgIcon v-if="form.show" name="check-circle-o" />
  137. <SvgIcon v-else name="shield-o" />
  138. {{ form.show ? $t('registerGateway.verificationSuccessful') : $t('common.verification') }}
  139. </AButton>
  140. </AFormItem>
  141. </AForm>
  142. </ACol>
  143. <ACol :span="17">
  144. <div>
  145. <img class="register-img" :src="deviceLabel" alt="" />
  146. </div>
  147. </ACol>
  148. </ARow>
  149. <div v-if="form.show" class="dev-card">
  150. <div class="dev-title">
  151. <AFlex :vertical="false">
  152. <div class="dev-title-signal" :style="ternaryExpression(false)"></div>
  153. <div class="dev-card-left-text">{{ ternaryExpression(true) }}</div>
  154. </AFlex>
  155. </div>
  156. <ARow style="padding: 0 30px 20px">
  157. <ACol :span="10">
  158. <AFlex justify="center" style="width: 100%" :vertical="true" align="center">
  159. <img class="dev-card-left-img" :src="imgUrl" alt="" />
  160. <div class="dev-card-left-text1">{{ props.form.modelName }}</div>
  161. <div class="dev-card-left-text2">
  162. {{ props.form.surfMode[0] }}|{{ props.form.surfMode[1] }}|{{ props.form.surfMode[2] }}
  163. </div>
  164. </AFlex>
  165. </ACol>
  166. <ACol :span="14">
  167. <div style="height: 140px">
  168. <ARow>
  169. <ACol :span="12">
  170. <AFlex justify="center" style="width: 100%" :vertical="true" align="center">
  171. <div style="height: 70px">
  172. <img class="dev-card-right-img" referrerpolicy="no-referrer" :src="deviceCard1" />
  173. <div class="dev-card-right-text">{{ interfaceNum?.COM }}*COM</div>
  174. </div>
  175. <div style="height: 70px">
  176. <img class="dev-card-right-img" referrerpolicy="no-referrer" :src="deviceCard2" />
  177. <div class="dev-card-right-text">{{ interfaceNum?.WAN }}*WAN</div>
  178. </div>
  179. </AFlex>
  180. </ACol>
  181. <ACol :span="12">
  182. <AFlex justify="center" style="width: 80%" :vertical="true" align="center">
  183. <div style="height: 70px">
  184. <img class="dev-card-right-img" referrerpolicy="no-referrer" :src="deviceCard3" />
  185. <div class="dev-card-right-text">{{ interfaceNum?.LAN }}*LAN</div>
  186. </div>
  187. <div style="height: 70px">
  188. <img
  189. class="dev-card-right-img"
  190. style="margin-top: -10px; margin-bottom: 0"
  191. referrerpolicy="no-referrer"
  192. :src="deviceCard4"
  193. />
  194. <div class="dev-card-right-text" style="margin-top: -5px">
  195. {{ interfaceNum?.DI }}*DI<br />{{ interfaceNum?.DO }}*DO
  196. </div>
  197. </div>
  198. </AFlex>
  199. </ACol>
  200. </ARow>
  201. </div>
  202. <div>
  203. <AButton class="dev-card-right-but" @click="productManual">
  204. <template #icon>
  205. <img class="dev-card-right-but-img" referrerpolicy="no-referrer" :src="deviceManual" /></template
  206. >{{ $t('registerGateway.productManual') }}</AButton
  207. >
  208. </div>
  209. </ACol>
  210. </ARow>
  211. </div>
  212. </div>
  213. </template>
  214. <style lang="scss" scoped>
  215. .ant-form-item {
  216. margin-bottom: 24px;
  217. }
  218. .dev-but {
  219. width: 130px;
  220. height: 40px;
  221. margin-top: 16px;
  222. }
  223. .dev-input {
  224. width: 256px;
  225. margin-left: 29px;
  226. }
  227. .dev-input1 {
  228. width: 256px;
  229. margin-left: 5px;
  230. }
  231. .register-img {
  232. width: 194px;
  233. height: 120px;
  234. margin-left: 24px;
  235. }
  236. .dev-card {
  237. width: 410px;
  238. height: 223px;
  239. padding-top: 10px;
  240. border-radius: 6px;
  241. box-shadow: 0 1px 3px 0 rgb(0 0 0 / 15%);
  242. }
  243. .dev-title {
  244. margin-left: 10px;
  245. }
  246. .dev-title-signal {
  247. width: 6px;
  248. height: 6px;
  249. margin-top: 6px;
  250. margin-right: 10px;
  251. border-radius: 50%;
  252. }
  253. .dev-card-left-text {
  254. font-size: 14px;
  255. font-style: normal;
  256. font-weight: 400;
  257. line-height: 17px;
  258. color: var(--antd-color-text-secondary);
  259. text-align: left;
  260. }
  261. .dev-card-left-img {
  262. width: 70px;
  263. height: 110px;
  264. }
  265. .dev-card-left-text1 {
  266. margin-top: 25px;
  267. font-size: 16px;
  268. font-style: normal;
  269. font-weight: 500;
  270. line-height: 18px;
  271. color: var(--antd-color-bg-spotlight);
  272. text-align: left;
  273. }
  274. .dev-card-left-text2 {
  275. margin-top: 5px;
  276. font-size: 14px;
  277. font-style: normal;
  278. font-weight: 400;
  279. line-height: 17px;
  280. color: var(--antd-color-text-secondary);
  281. text-align: center;
  282. }
  283. .dev-card-right-img {
  284. margin-bottom: 10px;
  285. margin-left: 30%;
  286. }
  287. .dev-card-right-text {
  288. font-size: 14px;
  289. font-style: normal;
  290. font-weight: 400;
  291. line-height: 22px;
  292. color: var(--antd-color-text-secondary);
  293. text-align: center;
  294. }
  295. .dev-card-right-but {
  296. width: 97px;
  297. height: 32px;
  298. padding: 0;
  299. margin-top: 10px;
  300. margin-left: 15%;
  301. border-radius: 4px;
  302. }
  303. .dev-card-right-but-img {
  304. margin-right: 8px;
  305. margin-bottom: 3px;
  306. }
  307. </style>