Here's the Gurobi code to solve the optimization problem:

```python
from gurobipy import Model, GRB, quicksum

# Create a new model
m = Model("optimization_problem")

# Create variables
jean_hours = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="jean_hours")  # Non-whole number of hours
bill_hours = m.addVar(lb=0, vtype=GRB.INTEGER, name="bill_hours")  # Whole number of hours

# Set objective function
m.setObjective(3 * jean_hours * jean_hours + 4 * bill_hours * bill_hours + jean_hours, GRB.MINIMIZE)

# Add constraints
m.addConstr(18 * jean_hours + 23 * bill_hours >= 75, "computer_competence_min")
m.addConstr(12 * jean_hours * jean_hours + 11 * bill_hours * bill_hours >= 62, "dollar_cost_min_squared")
m.addConstr(12 * jean_hours + 11 * bill_hours >= 62, "dollar_cost_min")
m.addConstr(4 * jean_hours - 8 * bill_hours >= 0, "jean_bill_relation")
m.addConstr(18 * jean_hours + 23 * bill_hours <= 89, "computer_competence_max")
m.addConstr(12 * jean_hours + 11 * bill_hours <= 124, "dollar_cost_max")


# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print('Optimal solution found:')
    print(f"Jean's hours: {jean_hours.x}")
    print(f"Bill's hours: {bill_hours.x}")
    print(f"Objective value: {m.objVal}")
elif m.status == GRB.INFEASIBLE:
    print('Model is infeasible')
else:
    print(f"Optimization ended with status {m.status}")

```
