jobPosting.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <template>
  2. <view class="switch-roles">
  3. <nav-bar title="选择公司规模" color="#000"></nav-bar>
  4. <view class="roles-content">
  5. <view class="content">
  6. <view class="title">发布社招</view>
  7. <view class="desc">{{companyName}}</view>
  8. <view class="step">
  9. <u-steps :list="numList" mode="number" :current="0" ></u-steps>
  10. </view>
  11. <view class="check-title">招聘类型</view>
  12. <view class="check-box">
  13. <view class="check-item" :class="{ 'is-check': check == index }" v-for="(item, index) in peopleList"
  14. :key="index" @click="checkPeople(index)">{{ item }}</view>
  15. </view>
  16. <view class="check-title-big">招聘职位</view>
  17. <view class="check-select" @click="goJob">
  18. <view class="select-txt">{{jobInfo.ruleClassifyName}}</view>
  19. <u-icon name="arrow-down" color="#D3D3D6" size="22"></u-icon>
  20. </view>
  21. <view class="check-title-big">岗位描述</view>
  22. <view class="check-select" @click="goJobContent">
  23. <view class="select-txt">{{
  24. this.text ? this.text : "介绍工作内容、职位要求"
  25. }}</view>
  26. <u-icon name="arrow-down" color="#D3D3D6" size="22"></u-icon>
  27. </view>
  28. <view class="txt-desc">注:职位名称、职位类型等发布后不可修改</view>
  29. </view>
  30. </view>
  31. <view class="submit-btn" @click="goJobPostingSecond">下一步</view>
  32. </view>
  33. </template>
  34. <script>
  35. import navBar from "@/components/nav-bar/index.vue";
  36. export default {
  37. data() {
  38. return {
  39. peopleList: ["社招全职", "应届生校园招聘", "实习生招聘", "兼职招聘"],
  40. check: 0,
  41. text: "",
  42. status:"",
  43. companyName: "",
  44. companyId:"",
  45. numList: [{
  46. name: "填写基本信息",
  47. },
  48. {
  49. name: "选择职位要求",
  50. },
  51. ],
  52. jobInfo: {
  53. ruleClassifyId: '',
  54. ruleClassifyName: '请选择要招聘的职位',
  55. price: ''
  56. }
  57. };
  58. },
  59. components: {
  60. navBar,
  61. },
  62. onLoad(options) {
  63. // 接收上个页面传递的公司名称参数
  64. if (options.companyName) {
  65. this.companyName = decodeURIComponent(options.companyName);
  66. console.log('接收的公司名称:', this.companyName);
  67. }
  68. this.descListener = uni.$on("jobDescUpdated", (data) => {
  69. console.log("收到岗位描述数据:", data);
  70. this.text = data.desc; // 赋值给当前页变量
  71. });
  72. this.jobListener = uni.$on('jobs', (data) => {
  73. console.log('接收从B页传来的数据:', data);
  74. // 手动更新 A 页的 data
  75. this.jobInfo = data;
  76. });
  77. if (options.companyId) {
  78. this.companyId = options.companyId;
  79. console.log('接收的公司ID:', this.companyId);
  80. }
  81. if (options.status) {
  82. this.status = decodeURIComponent(options.status);
  83. console.log('接收的公司状态:', this.status);
  84. }
  85. },
  86. onUnload() {
  87. // 页面卸载时移除监听,避免内存泄漏
  88. uni.$off('jobs', this.jobListener);
  89. },
  90. methods: {
  91. goBusinessLicense() {
  92. uni.navigateTo({
  93. url: "/pages/my/businessLicense"
  94. });
  95. },
  96. checkPeople(index) {
  97. this.check = index;
  98. },
  99. goJob() {
  100. uni.navigateTo({
  101. url: "/package/jobIntention/jobList",
  102. });
  103. },
  104. goJobContent() {
  105. uni.navigateTo({
  106. url: `/package/jobIntention/editJob`,
  107. });
  108. },
  109. //提交
  110. goJobPostingSecond() {
  111. // 显示加载中
  112. uni.showLoading({
  113. title: '提交中...'
  114. });
  115. //校验数据
  116. // 校验数据
  117. const validate = () => {
  118. // 2. 校验岗位描述(positionDetails)
  119. if (!this.text || this.text.trim() === '') {
  120. uni.hideLoading();
  121. uni.showToast({
  122. title: '岗位描述不能为空',
  123. icon: 'none',
  124. duration: 2000
  125. });
  126. return false;
  127. }
  128. if (this.text.length > 500) {
  129. uni.hideLoading();
  130. uni.showToast({
  131. title: '岗位描述不能超过500字',
  132. icon: 'none',
  133. duration: 2000
  134. });
  135. return false;
  136. }
  137. // 校验是否包含违规内容(简单示例,可根据实际需求扩展)
  138. const illegalChars = /QQ|微信|电话|手机号|\/|\\|\*|\?/g;
  139. if (illegalChars.test(this.text)) {
  140. uni.hideLoading();
  141. uni.showToast({
  142. title: '岗位描述不能包含联系方式或特殊符号',
  143. icon: 'none',
  144. duration: 2000
  145. });
  146. return false;
  147. }
  148. // 3. 校验岗位分类信息(假设ruleClassifyId是必选)
  149. if (!this.jobInfo?.ruleClassifyId) {
  150. uni.hideLoading();
  151. uni.showToast({
  152. title: '请选择岗位分类',
  153. icon: 'none',
  154. duration: 2000
  155. });
  156. return false;
  157. }
  158. if (!this.jobInfo?.ruleClassifyName) {
  159. uni.hideLoading();
  160. uni.showToast({
  161. title: '岗位分类名称异常,请重新选择',
  162. icon: 'none',
  163. duration: 2000
  164. });
  165. return false;
  166. }
  167. // 4. 校验orderId(如果有实际业务含义,可根据需求调整)
  168. // if (!this.orderId || this.orderId < 1) {
  169. // uni.hideLoading();
  170. // uni.showToast({
  171. // title: '订单信息异常',
  172. // icon: 'none',
  173. // duration: 2000
  174. // });
  175. // return false;
  176. // }
  177. // 所有校验通过
  178. return true;
  179. };
  180. // 执行校验,通过后再提交
  181. if (!validate()) {
  182. return; // 校验失败,终止提交
  183. }
  184. const data = {
  185. type: this.check,
  186. positionDetails: this.text,
  187. ruleClassifyId: this.jobInfo.ruleClassifyId,
  188. ruleClassifyName: this.jobInfo.ruleClassifyName,
  189. orderId:1
  190. }
  191. // 发送请求
  192. this.$Request.postJson("/app/postPush/savePostPush", data)
  193. .then((res) => {
  194. uni.hideLoading();
  195. if (res.code === 0) {
  196. uni.showToast({
  197. title: '提交成功',
  198. icon: 'success'
  199. });
  200. console.log("sssssss",this.companyId)
  201. // 提交成功后跳转到职位发布页面
  202. setTimeout(() => {
  203. uni.navigateTo({
  204. url: "/pages/my/jobPostingSecond?status="+this.status+"companyName="+this.companyName+'&companyId='+this.companyId
  205. });
  206. }, 1500);
  207. } else {
  208. uni.showToast({
  209. title: res.msg || '提交失败,请重试',
  210. icon: 'none'
  211. });
  212. }
  213. })
  214. .catch((err) => {
  215. uni.hideLoading();
  216. console.error('请求失败:', err);
  217. uni.showToast({
  218. title: '网络异常,请稍后重试',
  219. icon: 'none'
  220. });
  221. });
  222. }
  223. },
  224. };
  225. </script>
  226. <style lang="scss" scoped>
  227. .switch-roles {
  228. background-color: #fff;
  229. position: absolute;
  230. left: 0;
  231. right: 0;
  232. top: 0;
  233. bottom: 0;
  234. display: flex;
  235. flex-direction: column;
  236. .roles-content {
  237. width: 100%;
  238. flex: 1;
  239. overflow: hidden;
  240. overflow-y: auto;
  241. .content {
  242. padding: 40rpx;
  243. box-sizing: border-box;
  244. display: flex;
  245. flex-direction: column;
  246. align-items: center;
  247. justify-content: center;
  248. .title {
  249. color: #333;
  250. width: 100%;
  251. font-family: DM Sans;
  252. font-size: 40rpx;
  253. font-weight: 600;
  254. }
  255. .desc {
  256. color: rgba(102, 102, 102, 1);
  257. width: 100%;
  258. font-family: DM Sans;
  259. font-size: 24rpx;
  260. font-weight: 400;
  261. line-height: 32rpx;
  262. letter-spacing: 0.5%;
  263. text-align: left;
  264. padding: 20rpx 0;
  265. box-sizing: border-box;
  266. }
  267. .check-title {
  268. width: 100%;
  269. color: rgba(31, 44, 55, 1);
  270. font-family: DM Sans;
  271. font-size: 28rpx;
  272. font-weight: 500;
  273. line-height: 44rpx;
  274. margin-top: 20rpx;
  275. margin-bottom: 16rpx;
  276. }
  277. .check-title-big {
  278. color: rgba(58, 57, 67, 1);
  279. font-family: DM Sans;
  280. font-size: 36rpx;
  281. font-weight: 500;
  282. line-height: 48rpx;
  283. width: 100%;
  284. padding: 20rpx 0;
  285. box-sizing: border-box;
  286. }
  287. .check-select {
  288. width: 100%;
  289. display: flex;
  290. justify-content: space-between;
  291. align-items: center;
  292. border-radius: 12rpx;
  293. box-shadow: 0px 16rpx 300rpx 0px rgba(0, 0, 0, 0.06);
  294. background: rgba(255, 255, 255, 1);
  295. padding: 32rpx 47rpx;
  296. box-sizing: border-box;
  297. .select-txt {}
  298. }
  299. .check-box {
  300. width: 100%;
  301. display: grid;
  302. grid-template-columns: repeat(2, 1fr);
  303. gap: 24rpx;
  304. .check-item {
  305. border-radius: 16rpx;
  306. background: rgba(245, 248, 254, 1);
  307. color: rgba(153, 153, 153, 1);
  308. font-family: DM Sans;
  309. font-size: 28rpx;
  310. font-weight: 400;
  311. line-height: 44rpx;
  312. text-align: center;
  313. padding: 12rpx 48rpx;
  314. box-sizing: border-box;
  315. }
  316. .is-check {
  317. box-sizing: border-box;
  318. border: 1rpx solid #016bf6;
  319. border-radius: 16rpx;
  320. background: rgba(252, 233, 220, 1);
  321. color: #016bf6;
  322. }
  323. }
  324. }
  325. }
  326. .step {
  327. width: 100%;
  328. padding: 32rpx 0;
  329. box-sizing: border-box;
  330. }
  331. .submit-btn {
  332. flex-shrink: 0;
  333. border-radius: 999px;
  334. box-shadow: 0px 2px 4px 0px rgba(9, 196, 116, 0.3);
  335. background: linear-gradient(90deg, rgba(13, 39, 247, 1), rgba(19, 193, 234, 1) 100%);
  336. color: rgba(255, 255, 255, 1);
  337. font-family: DM Sans;
  338. font-size: 32rpx;
  339. font-weight: 400;
  340. line-height: 48rpx;
  341. display: flex;
  342. justify-content: center;
  343. align-items: center;
  344. padding: 16rpx 32rpx;
  345. box-sizing: border-box;
  346. margin: 60rpx 20rpx;
  347. }
  348. .txt-desc {
  349. color: rgba(102, 102, 102, 1);
  350. font-family: DM Sans;
  351. font-size: 24rpx;
  352. font-weight: 400;
  353. line-height: 32rpx;
  354. text-align: left;
  355. width: 100%;
  356. margin-top: 20rpx;
  357. }
  358. }
  359. </style>